Skip to main content
 首页 » 编程设计

python之python运行多线程被挂起

2024年12月31日31bjzhanghao

我在python中测试多线程,但是代码挂了:

class MongoInsertThread(threading.Thread): 
    def __init__(self,  queue, thread_id): 
        super(MongoInsertThread, self).__init__() 
        self.thread_id = thread_id 
        self.queue = queue 
 
    def run(self): 
        print(self.thread_id,': ', self.queue.get()) 
 
def save_to_mongo_with_thread(): 
    q = queue.Queue() 
    size = int(math.ceil(16 / 3)) 
 
    for e in range(size): 
        for i in range(e * size, min((e + 1) * size, 16)): 
            q.put([i], block=False) 
        threads = [] 
        for i in range(size): 
            threads.append(MongoInsertThread(q, i)) 
        for t in threads: 
            t.start() 
        for t in threads: 
            t.join() 
        print("+++++++++++++++++++++++") 

结果是我想要的,但是程序没有结束,结果是:

0 :  [0] 
1 :  [1] 
2 :  [2] 
3 :  [3] 
4 :  [4] 
5 :  [5] 
+++++++++++++++++++++++ 
0 :  [6] 
1 :  [7] 
2 :  [8] 
3 :  [9] 
4 :  [10] 
5 :  [11] 
+++++++++++++++++++++++ 
0 :  [12] 
1 :  [13] 
2 :  [14] 
3 :  [15] 

但是它不打印最后的++++++++++++++++++++++++,我该如何处理呢?

请您参考如下方法:

您正在调用 q.put() 16 次 - i in range(e * 5, (e + 1)*5) 对于每个 e in range(5) 产生

  1. i 在范围 (0, 5) 中
  2. 我在范围(5, 10)
  3. i 在范围 (10, 15) 内
  4. 我在范围(15, 16)
  5. 我在范围(20, 16)
  6. 我在范围(25, 16)

这会将 16 值附加到 q。但是,您创建了 25 线程,并关联了 25 对 q.get() 的调用 - 但一旦是第一个 16元素已被删除 get() block 。如果您使用 q.get(block=False) 代码将成功完成,但您会收到许多警告,从 get() 引发 Empty >。改变循环的循环条件

for i in range(size): 
  threads.append(MongoInsertThread(q, i)) 

到 range(e * size, min((e + 1) * size, 16))

将修复不匹配。但是,在添加和删除所有 16 元素之后,添加 break 语句以停止最外层的 for 循环也很有用。

完整示例

class MongoInsertThread(threading.Thread): 
    def __init__(self,  queue, thread_id): 
        super(MongoInsertThread, self).__init__() 
        self.thread_id = thread_id 
        self.queue = queue 
 
    def run(self): 
        print(self.thread_id,': ', self.queue.get(block=False)) 
 
def save_to_mongo_with_thread(): 
    q = Queue.Queue() 
    size = int(math.ceil(16 / 3)) 
    for e in range(5): 
        if (e*size > 16):  
            break 
        for i in range(e * size, min((e + 1) * size, 16)): 
            q.put([i], block=False) 
        threads = [] 
        for i in range(e * size, min((e + 1) * size, 16)): 
            threads.append(MongoInsertThread(q, i)) 
        for t in threads: 
            t.start() 
        for t in threads: 
            t.join() 
        print("+++++++++++++++++++++++") 

输出-

0: [0] 
1: [1] 
2: [2] 
3: [3] 
4: [4] 
+++++++++++++++++++++++ 
5: [5] 
6: [6] 
7: [7] 
8: [8] 
9: [9] 
+++++++++++++++++++++++ 
10: [10] 
11: [11] 
12: [12] 
13: [13] 
14: [14] 
+++++++++++++++++++++++ 
15: [15] 
+++++++++++++++++++++++ 

另请注意,我正在使用 get(block = False) 来帮助阐明 future 的问题,但对于此示例而言没有必要。