Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的多线程(我的代码正确吗)_Python_Multithreading - Fatal编程技术网

Python中的多线程(我的代码正确吗)

Python中的多线程(我的代码正确吗),python,multithreading,Python,Multithreading,我正在测试以下代码,我想确定它是否正确: from threading import Thread import cPickle def get_user(start, end): global users, vusers for j in range(start,end): if str(users[j]).find('@N') != -1: vusers.append(users[j]) if __name__ == '__mai

我正在测试以下代码,我想确定它是否正确:

from threading import Thread
import cPickle

def get_user(start, end):
    global users, vusers
    for j in range(start,end):
        if str(users[j]).find('@N') != -1:
            vusers.append(users[j])


if __name__ == '__main__':
    users = cPickle.load(open('nsid.dmp', 'r'))
    vusers = []
    jobs = [Thread(target=get_user, args=(0,1839))\
        ,Thread(target=get_user, args=(1840,3679))\
        ,Thread(target=get_user, args=(3680,5519))\
        ,Thread(target=get_user, args=(5520,7359))\
        ,Thread(target=get_user, args=(7360,9199))\
        ,Thread(target=get_user, args=(9200,11039))\
        ,Thread(target=get_user, args=(11040,12879))\
        ,Thread(target=get_user, args=(12880,14719))\
        ,Thread(target=get_user, args=(14720,16559))\
        ,Thread(target=get_user, args=(16560,18399))\
        ,Thread(target=get_user, args=(18400,20239))\
        ,Thread(target=get_user, args=(20240,20079))\
        ,Thread(target=get_user, args=(22080,23919))\
        ,Thread(target=get_user, args=(23920,25759))\
        ,Thread(target=get_user, args=(25760,27599))\
        ,Thread(target=get_user, args=(27600,29439))]
    for jb in jobs:
        jb.start()  
    for jb in jobs:
        jb.join()
    vusers = list(set(vusers))
    out = open('validu.dmp', 'w')
    cPickle.dump(vusers, out)
    out.close()

所以我要做的是以不同的范围并行运行函数
get\u user
。当然,函数
get\u user
比这更复杂,还有许多其他条件需要检查,但当我运行代码时,我看不出这更省时。我的代码中有什么错误吗?它是编写多线程函数的正确方法吗?如果没有,我如何使它并行运行?

由于GIL,这不会并行运行。我甚至不确定它是否会并发运行,因为每个目标函数似乎都不会放弃GIL(即没有系统调用等)


要绕过GIL,您需要使用多处理模块。当您使用多处理时,共享状态要困难得多,因此您需要重新组织代码,以收集程序主线程中每个子进程返回的答案。

我假设您出于性能原因希望共享状态。如果是这样的话,您可能应该使用进程而不是线程,那么您可以阅读更多关于python thead限制的内容

我非常喜欢
multiprocess.Pool
,它在后台使用
multiprocess.Process
。它允许您启动一些固定数量的进程,并为它们排队执行任务。下面是一个使用
pool.apply\u async
的示例,但我还将研究
pool.map
pool.map\u async

from multiprocessing import Pool

def get_user(users):
    return [u for u in users if 'N' in u]

def main(users):
    vusers = []
    results = []

    N = 2
    chunk = 200

    pool = Pool(N)
    for i in range(0, len(users), chunk):
        r = pool.apply_async(get_user, args=(users[i:i + chunk],))
        results.append(r)

    pool.close()
    pool.join()

    for r in results:
        vusers.extend(r.get())

    return vusers

if __name__ == '__main__':
    import random
    import string
    users = [random.sample(string.ascii_uppercase, 5) for i in range(10000)]
    vusers = main(users)

如果您想让它更快,请尝试
pypy
。但是,如果您想了解如何使用Python使算法以最佳方式并行执行,请使用回答中指出的
多处理
。请注意,它引入的复杂性稍高一些,因为您必须发送输入数据并检索输出数据并进行合成。@BrianCain如果我用多处理替换
线程
,它会工作吗。处理然后按此处所述收集数据:全局解释器锁定请参阅,或者我只是复制了您的代码,但它不工作。我得到以下错误:AttributeError:“module”对象没有属性“get\u user”。有没有解决这个问题的建议?Python使用pickle在进程之间发送信息。我怀疑pickle试图在另一个进程中导入
get\u user
函数,但不知怎么搞糊涂了。尝试将上述代码复制到具有新文件名的新文件中,这样应该可以正常工作。