处理有限数量的线程的列表

时间:2019-09-16 08:50:45

标签: python multithreading

我想处理一个线程数有限的列表,我希望它们轮流使用,直到列表为空。

我尝试了以下代码:

import threading


class testclass(threading.Thread):

    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):

        while List:
            threadLock.acquire()
            print ('This is thread :', self.name)
            testclass.test()
            threadLock.release()


    def test():
            print (List[0])
            List.pop(0)


List = [1, 2, 3, 4, 5]

threadLock = threading.Lock()

test1 = testclass('test1')
test2 = testclass('test2')
test1.start()
test2.start()

test1.join()
test2.join()

但是只有thread1可以处理整个列表。

root@user:/home/user# python3.7 test.py
This is thread : test1
1
This is thread : test1
2
This is thread : test1
3
This is thread : test1
4
This is thread : test1
5
This is thread : test2
Exception in thread test2:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "test.py", line 15, in run
    testclass.test()
  File "test.py", line 20, in test
    print (List[0])
IndexError: list index out of range
5

我如何让他们轮流浏览列表,然后在列表为空之前将其锁定?

提前谢谢!

2 个答案:

答案 0 :(得分:0)

您可以花很少的时间等待,以便另一个线程有时间“抢”资源:

import threading
import time


threadLock = threading.Lock()


class testclass(threading.Thread):

    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):

        while List:
            threadLock.acquire()
            print ('This is thread :', self.name)
            testclass.test()
            threadLock.release()
            time.sleep(0.01)


    def test():
            print (List[0])
            List.pop(0)


List = [1, 2, 3, 4, 5]


test1 = testclass('test1')
test2 = testclass('test2')
test1.start()
test2.start()

test1.join()
test2.join()

输出:

This is thread : test1
1
This is thread : test2
2
This is thread : test1
3
This is thread : test2
4
This is thread : test1
5

但是如果您要处理列表,我建议使用Pool.map

from multiprocessing.pool import Pool
import multiprocessing

List = [1, 2, 3, 4, 5]

def process_worker(x):
    print(f'[{multiprocessing.current_process().name}]process: {x}')

p = Pool(2) # set the amount of workers

p.map(process_worker, List)

输出:

[ForkPoolWorker-7]process: 1
[ForkPoolWorker-8]process: 2
[ForkPoolWorker-7]process: 3
[ForkPoolWorker-8]process: 4
[ForkPoolWorker-7]process: 5

答案 1 :(得分:0)

在线程化中,当当前执行线程处于任何I / O操作等待状态时,一个线程将在执行中并启动另一个线程。请参阅here

  

CPython实现细节:在CPython中,由于全局   解释器锁定,只有一个线程可以一次执行Python代码   (即使某些面向性能的库可能会克服   此限制)。如果您希望您的应用程序更好地利用   建议您使用多核计算机的计算资源   使用多重处理。但是,线程化仍然是合适的模型   如果要同时运行多个I / O绑定任务。

在这里,您还将使用带有默认值 blocking = True 的acquire()方法来阻止所有线程。请参阅https://docs.python.org/2/library/threading.html#lock-objects

即使在您使用 acquire(blocking = False)的情况下,也不会发生线程切换,因为没有I / O等待。