pythonでのマルチプロセスとマルチスレッドの組み合わせの使用

7494 ワード

pythonのマルチスレッドにはPILロックが存在するためpythonのマルチスレッドはマルチコアを利用できず,現在のコンピュータはマルチコアであるため,コンピュータのマルチコアリソースを十分に利用できない.しかしpythonのマルチプロセスは異なるcpu上を走ることができる.そこで,マルチプロセス+マルチスレッド方式でタスクを試みた.例えば、中科大のミラーソースから複数のrpmパケットをダウンロードします.
#!/usr/bin/python
import re
import commands
import time
import multiprocessing
import threading

def download_image(url):
    print '*****the %s  rpm begin to download *******' % url
    commands.getoutput('wget %s' % url)

def get_rpm_url_list(url):
    commands.getoutput('wget %s' % url)
    rpm_info_str = open('index.html').read()

    regu_mate = '(?<=)'
    rpm_list = re.findall(regu_mate, rpm_info_str)

    rpm_url_list = [url + rpm_name for rpm_name in rpm_list]
    print 'the count of rpm list is: ', len(rpm_url_list)
    return rpm_url_list
def multi_thread(rpm_url_list):
    threads = []
    # url = 'https://mirrors.ustc.edu.cn/centos/7/os/x86_64/Packages/'
    # rpm_url_list = get_rpm_url_list(url)
    for index in range(len(rpm_url_list)):
        print 'rpm_url is:', rpm_url_list[index]
        one_thread = threading.Thread(target=download_image, args=(rpm_url_list[index],))
        threads.append(one_thread)

    thread_num = 5  # set threading pool, you have put 4 threads in it
    while 1:
        count = min(thread_num, len(threads))
        print '**********count*********', count  ###25,25,...6707%25

        res = []
        for index in range(count):
            x = threads.pop()
            res.append(x)
        for thread_index in res:
            thread_index.start()

        for j in res:
            j.join()

        if not threads:
            break
def multi_process(rpm_url_list):
    # process num at the same time is 4
    process = []
    rpm_url_group_0 = []
    rpm_url_group_1 = []
    rpm_url_group_2 = []
    rpm_url_group_3 = []

    for index in range(len(rpm_url_list)):
        if index % 4 == 0:
            rpm_url_group_0.append(rpm_url_list[index])
        elif index % 4 == 1:
            rpm_url_group_1.append(rpm_url_list[index])
        elif index % 4 == 2:
            rpm_url_group_2.append(rpm_url_list[index])
        elif index % 4 == 3:
            rpm_url_group_3.append(rpm_url_list[index])
    rpm_url_groups = [rpm_url_group_0, rpm_url_group_1, rpm_url_group_2, rpm_url_group_3]
    for each_rpm_group in rpm_url_groups:
        each_process = multiprocessing.Process(target = multi_thread, args = (each_rpm_group,))
        process.append(each_process)

    for one_process in process:
        one_process.start()

    for one_process in process:
        one_process.join()

# for each_url in rpm_url_list:
#     print '*****the %s  rpm begin to download *******' %each_url
#
#     commands.getoutput('wget %s' %each_url)
def main():
    url = 'https://mirrors.ustc.edu.cn/centos/7/os/x86_64/Packages/'
    url_paas = 'http://mirrors.ustc.edu.cn/centos/7.3.1611/paas/x86_64/openshift-origin/'
    url_paas2 ='http://mirrors.ustc.edu.cn/fedora/development/26/Server/x86_64/os/Packages/u/'

    start_time = time.time()
    rpm_list = get_rpm_url_list(url_paas)
    print multi_process(rpm_list)
    # print multi_thread(rpm_list)
    #print multi_process()
    # print multi_thread(rpm_list)
    # for index in range(len(rpm_list)):
    #     print 'rpm_url is:', rpm_list[index]
    end_time = time.time()
    print 'the download time is:', end_time - start_time

print main()

コードの機能は主にmain()メソッドでget_を呼び出すことです.rpm_url_list(base_url)メソッドは、ダウンロードする各rpmパケットの具体的なurlアドレスを取得します.ここでbase_urlは、中科大学の基礎となるミラーソースのアドレスです.たとえば、次のようになります.http://mirrors.ustc.edu.cn/centos/7.3.1611/paas/x86_64/openshift-origin/あ、このアドレスの下には数十個のrpmパケットがあります.get_rpm_url_listメソッドは、各rpmパケットのurlアドレスをつづり、返します.multi_プロセス(rpm_url_list)は、マルチスレッドメソッドを呼び出すマルチプロセスメソッドを起動します.この方法は4つのマルチプロセスを開始し、上記の方法で得られたrpmパケットのurlアドレスをグループ化し、4つのグループに分け、各グループのrpmパケットは最後に異なるスレッドで実行される.これにより、マルチプロセス+マルチスレッドの組み合わせが可能になります.コードには、マルチプロセス起動のプロセス個数やrpmパケットのurlアドレスパケットがハードコーディングであるなど、改善すべき点もあります.これは、結局、異なるマシンでは、同時に起動するのに適したプロセス個数が異なります.