当我使用python测试多处理和线程时,我遇到了奇怪的情况

时间:2015-09-08 08:13:30

标签: python multithreading threadpool hyperthreading

我正在使用流程池(包括3个流程)。在每个进程中,我通过使用线程类来设置(创建)一些线程来加速处理某些事情。

起初,一切都很好。但是当我想在一个线程中更改某个变量时,我遇到了一个奇怪的情况。

为了测试或知道发生了什么,我设置了一个全局变量COUNT来测试。老实说,我不知道这是否安全。我只是想看看,通过使用多处理和线程我可以改变COUNT吗?

#!/usr/bin/env python
# encoding: utf-8

import os
import threading
from Queue import Queue
from multiprocessing import Process, Pool

# global variable
max_threads = 11
Stock_queue = Queue()
COUNT = 0

class WorkManager:
    def __init__(self, work_queue_size=1, thread_pool_size=1):
        self.work_queue = Queue()
        self.thread_pool = [] # initiate, no have a thread
        self.work_queue_size = work_queue_size
        self.thread_pool_size = thread_pool_size
        self.__init_work_queue()
        self.__init_thread_pool()

    def __init_work_queue(self):
        for i in xrange(self.work_queue_size):
            self.work_queue.put((func_test, Stock_queue.get()))

    def __init_thread_pool(self):
        for i in xrange(self.thread_pool_size):
            self.thread_pool.append(WorkThread(self.work_queue))

    def finish_all_threads(self):
        for i in xrange(self.thread_pool_size):
            if self.thread_pool[i].is_alive():
                self.thread_pool[i].join()

class WorkThread(threading.Thread):
    def __init__(self, work_queue):
        threading.Thread.__init__(self)
        self.work_queue = work_queue
        self.start()

    def run(self):
        while self.work_queue.qsize() > 0:
            try:
                func, args = self.work_queue.get(block=False)
                func(args)
            except Queue.Empty:
                print 'queue is empty....'

def handle(process_name):
    print process_name, 'is running...'
    work_manager = WorkManager(Stock_queue.qsize()/3, max_threads)
    work_manager.finish_all_threads()

def func_test(num):
    # use a global variable to test what happens
    global COUNT
    COUNT += num

def prepare():
    # prepare test queue, store 50 numbers in Stock_queue
    for i in xrange(50):
        Stock_queue.put(i)

def main():

    prepare()
    pools = Pool()
    # set 3 process
    for i in xrange(3):
        pools.apply_async(handle, args=('process_'+str(i),))
    pools.close()
    pools.join()

    global COUNT
    print 'COUNT: ', COUNT


if __name__ == '__main__':
    os.system('printf "\033c"')

    main()

现在,最后COUNT的结果只是0.我无法理解这里发生了什么?

1 个答案:

答案 0 :(得分:3)

您在父进程中打印COUNT var。变量不会跨进程同步,因为它们不共享内存,这意味着变量在父进程中保持为0并且在子进程中增加

在线程的情况下,线程共享内存,这意味着它们共享变量count,因此它们应该具有大于0的COUNT,但它们又在子进程中,并且当它们更改变量时,它不会在其他进程中更新它。