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
函数,但不知怎么搞糊涂了。尝试将上述代码复制到具有新文件名的新文件中,这样应该可以正常工作。