python - 如何在 Python 中并行调用一个 dll 函数

标签 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 ... ...

关于python - 如何在 Python 中并行调用一个 dll 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5759377/

相关文章:

.net - Windows 窗体 : A modal form that gets opened/closed by the application rather than the user?

python - 安装 SciPy 导入错误

c++ - 如何在 C++ 中确定一个 win32 线程处于 Wait 或 Join 或 Sleep 状态

Java 任务在循环后停止

python - 为什么这个 if 和 elif 语句没有完全执行?

c++ - 多线程代码中的文件 I/O 问题

c# - 启动和等待多个线程 - Resharper 提示修改后的闭包

python - pygame - 像素碰撞贴图

python - 无法再添加三个立方体

python - MPRIS + Python (dbus) : reading and writing properties