使用python循环的多线程处理

2024-06-10 01:42:55 发布

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

我试图在处理器的几个线程上运行这个Python代码,但是我找不到如何分配多个线程。我在Jupyter(以前叫I python)中使用的是python 2.7。 初始代码如下(所有这部分都工作得很好)。它是一个web解析器,它接受x,即我的列表中的一个url,即一个url列表,然后编写一个CSV(其中out_string是一行)。

不带多线程的代码

my_list = ['http://stackoverflow.com/', 'http://google.com']

def main():
    with open('Extract.csv'), 'w') as out_file:
        count_loop = 0
        for x in my_list:
            #================  Get title ==================#
            out_string = ""
            campaign = parseCampaign(x)
            out_string += ';' + str(campaign.getTitle())

            #================ Get Profile ==================#
            if campaign.getTitle() != 'NA':
                creator = parseCreator(campaign.getCreatorUrl())
                out_string += ';' + str(creator.getCreatorProfileLinkUrl())
            else:
                pass
            #================ Write ==================#
            out_string += '\n'
            out_file.write(out_string) 
            count_loop +=1
            print '---- %s on %s ------- ' %(count_loop, len(my_list))

多线程但无法工作的代码

from threading import Thread
my_list = ['http://stackoverflow.com/', 'http://google.com']

def main(x):
    with open('Extract.csv'), 'w') as out_file:
        count_loop = 0
        for x in my_list:
            #================  Get title ==================#
            out_string = ""
            campaign = parseCampaign(x)
            out_string += ';' + str(campaign.getTitle())

            #================ Get Profile ==================#
            if campaign.getTitle() != 'NA':
                creator = parseCreator(campaign.getCreatorUrl())
                out_string += ';' + str(creator.getCreatorProfileLinkUrl())
            else:
                pass
            #================ Write ==================#
            out_string += '\n'
            out_file.write(out_string) 
            count_loop +=1
            print '---- %s on %s ------- ' %(count_loop, len(my_list))

for x in my_list:
    t = Thread(target=main, args=(x,))
    t.start()
    t2 = Thread(target=main, args=(x,))
    t2.start()

我找不到一个好的方法来实现多个线程来运行这段代码,我有点困惑,因为文档不太容易理解。使用一个内核,这段代码需要2个小时,多线程将节省我很多时间!


Tags: 代码comloophttpgetstringmainmy
2条回答

嗯。。。答案是:

Why would you assign two threads for the same exact task?

是:

to run faster the loop

(见原帖评论)

然后这里出了点问题。

亲爱的OP,这两个线程会做完全相同的事情!这意味着第一个线程将执行与第二个线程完全相同的操作。

你能做的事情如下:

import multiprocessing

nb_cores = 2  # Put the correct amount

def do_my_process_for(this_argument):
  # Add the actual code
  pass

def main():

  pool = multiprocessing.Pool(processes=nb_cores)

  results_of_processes = [pool.apply_async(
      do_my_process, 
      args=(an_argument, ),
      callback=None
  ) for an_argument in arguments_list]

  pool.close()
  pool.join()

基本上,您可以认为每个进程/线程都有自己的“思想”。这意味着在您的代码中,第一个线程将执行在main()中为参数x(取自您列表中的迭代)定义的进程,第二个线程将再次执行相同的任务(在main()中的任务)。

你需要的是把你的过程描述成一个有一组输入参数和一组输出的过程。然后您可以创建多个进程,为每个进程提供一个所需的输入参数,然后进程将使用适当的参数执行您的主例程。

希望有帮助。再看看代码,我想你会理解的。

另外,请参见:

多处理映射和异步映射(我现在不记得确切的名称)

以及

函数工具部分

好吧,让我们来分析一下你的问题。

首先,main()方法处理文件的所有输入和输出。当您将main与两个线程一起使用时,两个线程将完成相同的工作。您需要一个只处理一个输入并返回该输入的输出的方法。

def process_x(x):
    #================  Get title ==================#
    out_string = ""
    campaign = parseCampaign(x)
    out_string += ';' + str(campaign.getTitle())

    #================ Get Profile ==================#
    if campaign.getTitle() != 'NA':
        creator = parseCreator(campaign.getCreatorUrl())
        out_string += ';' + str(creator.getCreatorProfileLinkUrl())
    else:
        pass
    #================ Write ==================#
    out_string += '\n'
    return out_string

现在可以在多个线程中调用此方法,并分别获取每个x的输出。

from threading import Thread
my_list = ['http://stackoverflow.com/', 'http://google.com']
threads = list()
for x in my_list:
    t = Thread(target=process_x, args=(x,))
    t.start()

但问题是这将启动n个线程,其中n是我的目录中的元素数。所以,使用^{}会更好。所以,用

from multiprocessing import Pool
pool = Pool(processes=4)              # start 4 worker processes
result_list = pool.map(process_x, my_list)

这里将有所有列表的结果。所以现在你可以把它保存在文件里了。

with open('Extract.csv'), 'w') as out_file:
    out_file.writelines(result_list)

相关问题 更多 >