2015-11-06 97 views
0

我在尋找C模擬tempfile.NamedTemporaryFile()函數以便並行使用Cython代碼沒有GIL。從理論上講tmpnam功能,可以做的伎倆:使用Cython命名臨時文件

with nogil, parallel.parallel(): 
     fname = tmpnam(NULL) 
        ^
------------------------------------------------------------ 

testc2.pyx:9:23: Converting to Python object not allowed without gil 

我不明白,其中:

from cython import parallel 
from libc.stdio cimport FILE, tmpnam, fopen, fclose, fwrite 
from libcpp.string cimport string 

cdef save_obj(string obj): 
    cdef char* fname 
    cdef FILE* cfile 
    with nogil, parallel.parallel(): 
     fname = tmpnam(NULL) 
     cfile = fopen(fname, "wb") 
     fwrite(obj.data(), 1, obj.size(), cfile) 
     fclose(cfile) 

但是,由於某種原因,它仍然無法正常工作,因爲我在編譯過程中出現以下錯誤這個python對象來自於,功能來自C

有人可以解釋我,爲什麼它仍然需要GILtmpnam,我怎麼能克服這個問題?

+1

'tmpnam'明確不是線程安全的(將其寫入了開始時的靜態緩衝區 - 見http://stackoverflow.com/questions/1145048/cc-thread-safety-of-tmpnam和更多細節)。因此,試圖在並行部分使用它是一個非常糟糕的主意。如果你不需要文件名'tmpfile'可能是一個更好的選擇。如果你需要文件名並且在unix上查看'mkstemp'。 – DavidW

回答

1

所有關於導入C標準庫中的函數的Cython信息都來自pxd文件中的信息,這些信息與頭文件類似。 Cython捆綁了C標準庫標題的幾個pxd文件,其中包括stdio.pxdlink。這是你從代碼的第二行導入的內容。

如果您檢查鏈接,您會發現tmpnam沒有在綁定的stdio.pxd中定義,因此Cython猜測您在該上下文中使用了Python名稱。您還可以導入的功能,但你必須提供一個原型:

cdef extern from "stdio.h" nogil: 
    char* tmpnam(char*);