我有一个读取文件的函数,将该文件中的记录与另一个文件中的记录进行比较,并根据规则将文件中的记录追加到两个列表中的一个列表中。
我有一个空列表,用于将匹配的结果添加到:
restrictions
我有一个列表match
,我希望将一系列文件中的记录与。
我有一个函数可以读取我希望看到的文件是否包含任何匹配项。如果匹配,我会将记录附加到def link_match(file):
links = json.load(file)
for link in links:
found = False
try:
for other_link in other_links:
if link['data'] == other_link['data']:
match.append(link)
found = True
else:
pass
else:
print "not found"
列表。
list_files=[]
for file in glob.glob("/path/*.json"):
list_files.append(file)
我有许多我希望比较的文件,因此我希望使用多处理库。
我创建一个文件名列表作为函数参数:
map
然后我使用if __name__ == '__main__':
pool = multiprocessing.Pool(processes=6)
pool.map(link_match,list_files)
pool.close()
pool.join()
功能使用不同的输入文件调用该函数:
match
CPU使用通过屋顶,通过在函数循环中添加打印行,我可以看到正在找到匹配并且函数表现正常。
但是,$cmd="curl -XGET 'https://lookups.twilio.com/v1/PhoneNumbers/+1201832xxxx?Type=carrier&Type=caller-name' -u 'clientidxxxxxx:clienttokenxxxxxx' ";
$result=shell_exec($cmd);
$response = json_decode($result);
echo "<pre>"; print_r($response); echo "</pre><br/>";
结果列表仍为空。我做错了什么?
答案 0 :(得分:1)
多处理创建多个进程。你&#34;匹配的背景&#34;变量现在将在该子进程中,而不是启动处理的父Python进程。
尝试将列表结果写入函数中的文件以查看我的意思。
答案 1 :(得分:1)
要扩展cthrall的答案,您需要从函数中返回一些内容,以便将信息传递回主线程,例如
def link_match(file):
[put all the code here]
return match
[main thread]
all_matches = pool.map(link_match,list_files)
将从每个单个线程返回列表match
,map
将返回此列表中的列表列表。然后,您可以flatten再次获得最终输出。
或者你可以使用shared list,但这会让我更加头疼。
答案 2 :(得分:1)
multiprocessing
为池中的每个进程运行一个新的Python实例 - 上下文为空(如果使用spawn
作为启动方法)或复制(如果使用fork
),以及你传递的任何参数的副本(无论哪种方式),并从那里他们全部分开。如果您想在分支机构之间传递数据,还有其他几种方法可以实现。
multiprocessing
,但使用multiprocessing.Queue
代替列表。这是专门为您当前的用例提供的对象:使用多个进程并需要在它们之间传递数据。假设您确实应该使用multiprocessing
(您的情况对threading
不会更好,请参见下文),这可能是您的最佳选择。threading
而不是multiprocessing
。单独的线程都共享一个环境。这里最大的问题是Python只允许一个线程实际上每个进程运行Python代码。这称为全局解释器锁(GIL)。因此,当线程在外部进程(其他程序,用户输入,读取或写入文件)上等待时,threading
非常有用,但如果大部分时间都花在Python代码上,那么它实际上需要更长的时间(因为它需要更长的时间)一点时间切换线程,你没有做任何事情来节省时间)。它有自己的queue
。如果你使用threading
,你应该使用它而不是普通的列表 - 否则,如果它在错误的情况下切换线程,则两个线程同时访问列表的可能性相互干扰时间。哦,顺便说一下:如果你确实使用了线程,那么Python 3.2及更高版本的GIL实现了改进,看起来它至少有很好的帮助机会。很多线程性能的东西很大程度上取决于你的硬件(CPU核心数量)和你正在做的确切任务 - 可能最好尝试几种方法,看看哪些方法适合你。
答案 3 :(得分:1)
当进行多处理时,每个子进程都会获得自己在if __name__ == '__main__':
语句之前定义的主模块中的任何全局变量的副本。这意味着每个进程中的link_match()
函数将访问代码中的不同的 match
列表。
一种解决方法是使用共享列表,这又需要SyncManager来同步对进程间共享资源的访问(通过调用multiprocessing.Manager()
创建)。然后,这将用于创建列表以在下面的代码中存储结果(我将其命名为matches
而不是match
)。
我还必须使用functools.partial()
创建一个可以从修订后的link_match
函数调用的单个参数,该函数现在需要两个参数,而不是一个(函数pool.map()
期望的那种) )。
from functools import partial
import glob
import multiprocessing
def link_match(matches, file): # note: added results list argument
links = json.load(file)
for link in links:
try:
for other_link in other_links:
if link['data'] == other_link['data']:
matches.append(link)
else:
pass
else:
print "not found"
if __name__ == '__main__':
manager = multiprocessing.Manager() # create SyncManager
matches = manager.list() # create a shared list here
link_matches = partial(link_match, matches) # create one arg callable to
# pass to pool.map()
pool = multiprocessing.Pool(processes=6)
list_files = glob.glob("/path/*.json") # only used here
pool.map(link_matches, list_files) # apply partial to files list
pool.close()
pool.join()
print(matches)