在 Cython 中使用自定义 Python 对象发布 GIL?

问题描述

我正在尝试对一些代码进行多线程处理。多处理占用太多内存,因为数据集不是在每个进程中共享的,而是为每个进程克隆的。也就是说,我有 100/100/100/100,而不是 4 个进程的 25/25/25/25。

由于 Python 使用全局解释器锁,多线程并发运行并且一切都比我根本不使用它要慢 - 所以我尝试使用 Cython 并使用 with nogil: 释放 gil。我知道操作 Python 对象的限制,但是有没有一种方法可以简单地引用一个而不实际操作它?

目前,我有两个文件(它们很大,所以我只会展示一个类似的结构):

vecmodeltest.pyx

    cpdef int run_me(string w,vector[string] doc,vectormodel):
        cdef int count=0
        cdef string t
        with nogil:
            for t in doc:
                if vecmodel.simi(w,t)>0.2:
                    count+=1
    return count

vecmodel.py

    import vecmodeltest as vm
    
    class VecModel(object):
       def _init_(self):
          pass
       def simi(self,w1,w2):
          s1 = set(w1)
          s2 = set(w2)
          i = len(s1.intersection(s2))
          return float(i / len(s1.union(s2)))
    
    _word = "hello"
    doc = "hello this is a hell document".split()
    vecmodel = VecModel()
    
    vm.run_me(_word,doc,vecmodel)

我在尝试构建 Cython 文件时收到 vecmodeltest.pyx:6:35: Converting to Python object not allowed without gil错误,对于这一行:if vecmodel.simi(w,t)>0.2:。我尝试在整个文件的不同位置进入和退出 GIL,但一直在努力处理 Python 对象。

也许我处理这个问题的方式有误,但目前是否有任何解决方案可以在 Cython 中使用自定义 Python 对象?

先谢谢大家!

解决方法

最好将文档和词转换成集合,然后不通过类对象运行相似度。这样您就可以使用 Multi-processing 而无需传递大型模型。