多线程不完整?

时间:2019-07-12 00:17:34

标签: python python-multithreading pool

我有以下Python代码:

pool = ThreadPool(32)
l = defaultdict(lambda: 0)

def func(e):
    if "$" in e:
        l["included"] += 1
    else:
        l["not_included"] += 1

with open(file_name) as file:
    data = file_name.readlines()

pool.map(func, data)

with open("output/logs.txt") as file:
    file.write(l)

从本质上讲,它正在文件中寻找包含字符“ $”的行。但是,每次执行代码时,该输出文件都是不同的,这意味着要附加的列表l是不同的。可能是什么原因造成的?

令人困惑的部分是,所产生的defaultdict l与每次执行都不同。有时l = {"included": 772, "not_included": 9992},有时l = {"included": 878, "not_included": 6907}

2 个答案:

答案 0 :(得分:0)

func的每个操作都花费不同的时间。考虑:

>>> from multiprocessing.dummy import Pool as ThreadPool
>>> from random import randrange
>>> min_time = 0
>>> max_time = 4
>>> import time
>>> pool = ThreadPool(4)
>>> lst = []
>>> def func(e):
...     time.sleep(randrange(min_time, max_time))
...     lst.append(e ** 2)
... 
>>> data = list(range(20))
>>> pool.map(func, data)
>>> lst
[0, 4, 1, 36, 9, 16, 100, 121, 64, 81, 144, 49, 25, 169, 256, 289, 196, 225, 324, 361]

每个线程调用func,但是花费的时间不同。由于有多个线程同时运行,因此不能保证以任何顺序追加线程。 也许第一个线程从输入0开始,但是需要2秒钟,但是第二个线程从1开始,并且花费不到一秒钟。在这种情况下,将首先附加以1调用func的结果。

编辑:我假设文件的长度是相同的,而顺序是不同的。

答案 1 :(得分:0)

因为map()从线程返回值,所以我用它返回True或False,然后在主线程中计数它们。这样,线程就不会尝试使用通常会造成问题的同一l

from multiprocessing.pool import ThreadPool

pool = ThreadPool(32)

def func(e):
    return "$" in e

data = ['$','$','x','$','$','x','$','$','x','x','$','x','x']

results = pool.map(func, data)

print(results)

l = dict()
l["included"] = results.count(True)
l["not included"] = results.count(False)

print(l)

结果

[True, True, False, True, True, False, True, True, False, False, True, False, False]
{'included': 7, 'not included': 6}

问题是当一个线程正在更改值但不阻止对变量的访问时,因此同时另一个线程获得旧值而不是新值,并且它修改了该旧值并将其放回变量,从而产生错误结果。线程必须使用一些Lock或Semaphor来阻止对变量的访问。