注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[python] GIL (global interpreter lock)  

2012-08-23 18:49:35|  分类: lang_python |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
GIL, The mechanism used by the CPython interpreter to assure that only one thread executes Python bytecode at a time. 

python 的多线程是 OS native thread,这些 thread 又共享 py vm。所以在 python 搞了个 gil,如
thread {
  ...
  releaseGIL();
  ...               // os I/O, fread()/fwrite()/...
  grabGIL();
  ...
}
通过 GIL 保证同一时间,只有一条线程可以访问 python vm。

GIL的实现代码:Python\pystate.c

关于 GIL 的性能,我测试了下
no GIL,两次测试结果  116700  115904
GIL,两次测试结果   96772  96588
2秒内,相差不大,对于 I/O intensive 很有用;如果是 CPU intensive 就悲剧了。

不过这里有个要注意的地方,在 g_lock.give() 和 g_lock.grab() 之间的代码,需要 thread-safe。
下面 threadFunc() 中的 ReadFile(hFile, buf, 80, &readed, NULL) 就 not thread-safe,因为用了全局变量 buf。

#include <Windows.h>
#include <stdio.h>
#include <process.h>

#define FILE_NAME "D:\\test.txt"

class MyMutex
{
public:
  MyMutex()
  {
    InitializeCriticalSection(&cs_);
  }
  ~MyMutex()
  {
    DeleteCriticalSection(&cs_);
  }

  void grab()    
  {
    EnterCriticalSection(&cs_);
  }
  void give()    
  {
    LeaveCriticalSection(&cs_);
  }
private:
  CRITICAL_SECTION  cs_;
};

MyMutex g_lock;
char buf[80];
int count = 0;

unsigned __stdcall threadFunc( void * arg )
{
  int n = (int)arg;
  while (1)
  {
    g_lock.grab();
    DWORD readed;

    g_lock.give();
    HANDLE hFile = ::CreateFile(FILE_NAME, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, 0);
    ::ReadFile(hFile, buf, 80, &readed, NULL);
    g_lock.grab();

    buf[readed] = '\0';
    // printf("#%d read %s\n", n, buf);
    count++;

    ::CloseHandle(hFile);
    g_lock.give();
  }
}

unsigned __stdcall threadFunc2( void * arg )
{
  int n = (int)arg;
  while (1)
  {
    char buf[80];
    DWORD readed;

    HANDLE hFile = ::CreateFile(FILE_NAME, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, 0);
    ::ReadFile(hFile, buf, 80, &readed, NULL);

    buf[readed] = '\0';
    // printf("#%d read %s\n", n, buf);
    count++;

    ::CloseHandle(hFile);
  }
}

int main()
{
  for (int i = 0; i < 10; i++)
  {
    unsigned int threadId;
    _beginthreadex(0, 0, threadFunc2, (void*)i, 0, &threadId);
  }

  Sleep(2*1000);
  printf("cnt:%d\n", count);
  return 0;
}


这又有一个问题,既然 python 有了 GIL,为何还会提供一些 lock 机制呢?
因为 python 内部还有个 scheduler,每个线程在执行了一定时间片后,会放出 cpu,所以还是需要 lock 来保证多线程访问共享数据的情况。
  评论这张
 
阅读(1399)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017