正在获取OSError:[WinError 87]和Type Error:无法使_thread.lock对象腌制

时间:2019-07-13 16:34:14

标签: python multithreading multiprocessing

我将继续阅读一本名为Python Web Scraping-第二版的Packt书,其中的参考代码来自https://github.com/kjam/wswp/tree/master/code/chp4 而且我的帖子标题中总是出现错误。

代码确实可以在macOS上运行,并且据我了解,问题可能出在Windows和Linux之间的fork vs spawn差异上。我是多处理的新手,无法弄清楚需要更改哪些内容和位置才能使其在Windows上正确运行。任何帮助表示赞赏。

基于在SO上的一些挖掘,我尝试了multiprocessing.set_start_method(“ spawn”)无济于事。

 julia> a = [1,2,3]          
 3-element Array{Int64,1}:   
 1                          
 2                          
 3                          

 julia> b = [1,2,3]          
 3-element Array{Int64,1}:   
 1                          
 2                          
 3                          

 julia> a .* b               
 3-element Array{Int64,1}:   
 1                          
 4                          
 9                          

错误:

import multiprocessing
import time



def threaded_crawler_rq(start_url, link_regex, user_agent='wswp', proxies=None,
                        delay=3, max_depth=4, num_retries=2, cache={}, max_threads=10, scraper_callback=None):
    """ 
     Comments
    """



def mp_threaded_crawler(*args, **kwargs):
    """ create a multiprocessing threaded crawler """
    processes = []
    num_procs = kwargs.pop('num_procs')
    if not num_procs:
        num_procs = multiprocessing.cpu_count()
    for _ in range(num_procs):
        proc = multiprocessing.Process(target=threaded_crawler_rq,
                                       args=args, kwargs=kwargs)
        proc.start()
        processes.append(proc)

    # wait for processes to complete
    for proc in processes:
        proc.join()


if __name__ == '__main__':
    from chp4.alexa_callback import AlexaCallback
    from chp3.rediscache import RedisCache
    import argparse

    parser = argparse.ArgumentParser(description='Multiprocessing threaded link crawler')
    parser.add_argument('max_threads', type=int, help='maximum number of threads',
                        nargs='?', default=5)
    parser.add_argument('num_procs', type=int, help='number of processes',
                        nargs='?', default=None)
    parser.add_argument('url_pattern', type=str, help='regex pattern for url matching',
                        nargs='?', default='$^')
    par_args = parser.parse_args()

    AC = AlexaCallback()
    AC()
    start_time = time.time()

    mp_threaded_crawler(AC.urls, par_args.url_pattern, cache=RedisCache(),
                        num_procs=par_args.num_procs, max_threads=par_args.max_threads)
    print('Total time: %ss' % (time.time() - start_time))

1 个答案:

答案 0 :(得分:0)

至少在Windows中,您提供给将在工作进程中运行的功能的参数通过引擎盖下的IPC通道传递给该进程。

因此,您无法将argskwargs中的不可拾取对象传递给multiprocessing.Process()

(venv) C:\Users\Sasha\Documents>pip install ipdb
<...>
(venv) C:\Users\Sasha\Documents>ipdb3 t.py
> c:\users\sasha\documents\t.py(1)<module>()
----> 1 import multiprocessing
      2 import time
      3

ipdb> b 23
Breakpoint 1 at c:\users\sasha\documents\t.py:23
ipdb> c
> c:\users\sasha\documents\t.py(23)mp_threaded_crawler()
     22                                        args=args, kwargs=kwargs)
1--> 23         proc.start()
     24         processes.append(proc)

ipdb> p args
(['http://google.com', 'http://youtube.com', 'http://facebook.com', 'http://baidu.com', <...>
ipdb> p kwargs
{'cache': <chp3.rediscache.RedisCache object at 0x000000000560F780>, 'max_threads': 5}
ipdb> import pickle
ipdb> pickle.dumps(kwargs)
*** TypeError: can't pickle _thread.lock objects

对象不会无缘无故地被拾取。通常,这意味着它们所代表的任何内容(例如同步化原语或网络连接)本质上都是过程本地的,因此尝试将其传递给另一个进程毫无意义。