Python线程锁定/类变量初始化混乱

2024-09-28 22:21:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类,如果被多个线程访问,它的行为会很奇怪。这些线程是在sklearn的GridSearch培训期间开始的(jobs=3),所以我不知道它们是如何被调用的。在

我的类本身大致如下:

from sklearn.base import BaseEstimator, TransformerMixin
import threading

class FeatureExtractorBase(BaseEstimator, TransformerMixin):
    expensive_dependency = {}
    lock = threading.lock()
    is_loaded = False

    @staticmethod
    def load_dependencies():
        FeatureExtractorBase.lock.acquire()
        if not FeatureExtractorBase.is_loaded:
            print('first request, start loading..')
            # load dependencies, takes a while
            FeatureExtractorBase.is_loaded = True
            print('done')
        else:
            pass
        FeatureExtractorBase.lock.release()

class ActualExtractor(FeatureExtractorBase):
    def transform(self, data):
        FeatureExtractorBase.load_dependencies()
        # generate features from data using dependencies
        return features

这个类使用我希望的惰性初始化。立即初始化会导致问题,我不能再这样做了。而且由于类在一个程序调用期间会被重新初始化几次,所以每次初始化构造函数中的数据都会浪费时间。现在,问题是 这不是我想要的,这是输出:

^{pr2}$

不仅在同一时间输入三个我认为是锁定区域的线程,在一分钟后的测试中,同样的区域再次进入——尽管此时is_loaded应该设置为True。在

这是我第一次用Python处理线程,而且我对类的处理仍然很笨拙,所以我确信我在这里做了些错事。但我看不到什么或哪里。在


Tags: fromimportlockisdefloaddependenciessklearn
1条回答
网友
1楼 · 发布于 2024-09-28 22:21:21

线程本身并不能加快python进程的速度,其瓶颈是CPU而不是IO(读/写),因为全局解释器锁(GIL)。 多任务加速实际上是用来学习并行处理的。这与线程的不同之处在于,对象被复制到一个单独的进程中,因此您的类实际上有多个副本。 因此,每次启动新进程时,都会复制原始的、未初始化的类,然后再次进行加载。在

我认为这是sklearn用于网格搜索的主要并行化模块。 https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/externals/joblib/parallel.py

相关问题 更多 >