Scr*_*ter 3 python multithreading
我有一个python程序,它使用ctypes来调用我传递指针的dll函数.它应该连续地向该指针写入数据,我希望我的程序循环并读取指针内容.粗略的模板看起来像:
from ctypes import *
import copy
lib = cdll.lib
pointer = c_char_p(" "*100) #however large a buffer I need
#thread this
lib.dostuff(pointer)
#end thread
while True:
    data = pointer.value
    print data
在我的特定情况下,dostuff()是用C语言编写的,它打开一个文件并对其进行解码,将数据作为流运行到字符数组中.
问题是我不能在python中使用常规线程模块,因为线程持有GIL,因为读取dll被认为是文件I/O,或者因为dll本身就是文件I/0.因此,在dostuff()完成之前,循环不会运行.它阻塞的原因是什么(将dll调用总是阻塞?)以及如何解决这个问题?
编辑:----------已解决----------------------正如samplebias指出的那样,ctypes释放了GIL锁定.我发现程序中的阻塞问题是我正在运行队列:代码看起来有点像这样
import Queue
from threading import Thread
queue = Queue()
def runthread():
     lib.dostuff(pointer)
     while True:
        queue.put(pointer.value)
thread = Thread(target=runthread)
thread.start()
while True:
    data = queue.get()
    dostuffwithdata(data)
该程序是阻塞的,因为当队列为空时queue.get()会阻塞,直到有东西进入!当然,因为我没有单独调用dll调用,所以在我将指针结果推送到队列之前完成了.解决方案看起来有点像这样:
import Queue
from threading import Thread
queue = Queue()
def runthread():
     q = Thread(target=lib.dostuff, args=(pointer,))
     q.start()
     while True:
         queue.put(pointer.value)
thread = Thread(target=runthread)
thread.start()
while True:
   data = queue.get()
   dostuffwithdata(data)
我希望这可以帮助别人!
这绝对可以使用线程,因为ctypes在调用C函数之前释放GIL.这使得(除其他事项外)C例程能够在不产生死锁的情况下回调Python代码.  
关于你将遇到的唯一问题是如何向DLL发出信号以停止传递数据,但也有办法解决这个问题,例如,将第二个指针作为指示何时返回的标志传递.
这是一个与您的问题相关的工作示例,例如,GIL已发布,Python和C代码同时运行:
共享对象:test.c
#include <stdint.h>
#include <stdio.h>
void
dostuff(uint64_t *ptr)
{
    while (1)
        (*ptr)++;
}
编译它:
% gcc -shared -g -o test.so test.c -fPIC
Python代码:test.py
import ctypes
import sys
import time
import threading
lib = ctypes.cdll.LoadLibrary('./test.so')
val = ctypes.c_uint64(0)
def loop():
    lib.dostuff(ctypes.byref(val))
t1 = threading.Thread(target=loop)
t1.start()
for i in range(1000):
    sys.stdout.write('%s ' % val.value)
    sys.stdout.flush()
    time.sleep(0.05)
产量
% python test.py 
0 24664442 48388062 71628820 94834416 118004961 141095893 164936784 ... ...