访问两个线程进程之间的数据

时间:2014-05-23 14:15:06

标签: python multithreading process

我们正在尝试访问两个线程之间的数据,但无法完成此操作。我们正在寻找一种简单(优雅)的方式。

这是我们当前的代码。 目标:完成第二个主题/流程后,实例listHolder中的B必须包含2个项目。

Class A:
   self.name = "MyNameIsBlah"

Class B:
   # Contains a list of A Objects. Is now empty.
   self.listHolder = []

   def add(self, obj):
      self.listHolder.append(obj)

   def remove(self, obj):
      self.listHolder.remove(obj)

def process(list):
    # Create our second instance of A in process/thread
    secondItem = A()
    # Add our new instance to the list, so that we can access it out of our process/thread.
    list.append(secondItem)

# Create new instance of B which is the manager. Our listHolder is empty here. 
manager = B()

# Create new instance of A which is our first item
firstItem = A()

# Add our first item to the manager. Our listHolder now contains one item now.
b.add(firstItem)

# Start a new seperate process.
p = Process(target=process, args=manager.listHolder)

# Now start the thread
p.start()

# We now want to access our second item here from the listHolder, which was initiated in the seperate process/thread.

print len(manager.listHolder) << 1
print manager.listHolder[1] << ERROR
  • 预期输出:A中的listHolder个实例。
  • 获得输出:A中的listHolder个实例。

我们如何使用分离的进程/线程访问管理器中的对象,这样它们就可以以非线程阻塞的方式同时运行两个函数。

目前我们正在尝试使用流程来实现这一目标,但如果线程能够以更简单的方式实现此目标,那么这不是问题。使用Python 2.7。

更新1:

@James Mills使用&#34; .join()&#34;回复。但是,这将阻止主线程,直到第二个进程完成。我尝试使用它,但本例中使用的Process将永远不会停止执行(同时为True)。它将充当计时器,必须能够迭代到列表从列表中删除对象

任何人都有任何建议如何完成此操作并修复当前的cPickle错误?

2 个答案:

答案 0 :(得分:2)

如果詹姆斯·米尔斯的回答对你不起作用,这里有一篇关于如何使用队列来显式地向工人进程发送数据的文章:

#!/usr/bin/env python

import logging, multiprocessing, sys


def myproc(arg):
    return arg*2

def worker(inqueue, outqueue):
    logger = multiprocessing.get_logger()
    logger.info('start')
    while True:
        job = inqueue.get()
        logger.info('got %s', job)
        outqueue.put( myproc(job) )

def beancounter(inqueue):
    while True:
        print 'done:', inqueue.get()

def main():
    logger = multiprocessing.log_to_stderr(
            level=logging.INFO,
    )
    logger.info('setup')

    data_queue = multiprocessing.Queue()
    out_queue = multiprocessing.Queue()

    for num in range(5):
        data_queue.put(num)

    worker_p = multiprocessing.Process(
        target=worker, args=(data_queue, out_queue), 
        name='worker',
    )
    worker_p.start()

    bean_p = multiprocessing.Process(
        target=beancounter, args=(out_queue,),
        name='beancounter',
        )
    bean_p.start()

    worker_p.join()
    bean_p.join()
    logger.info('done')


if __name__=='__main__':
    main()

来自:Django multiprocessing and empty queue after put

使用多处理管理器处理数据的另一个例子是:

http://johntellsall.blogspot.com/2014/05/code-multiprocessing-producerconsumer.html

答案 1 :(得分:0)

Sharing state between processes最简单的方法之一是使用multiprocessing.Manager类在进程之间同步数据(通常使用Queue ):

示例:

from multiprocessing import Process, Manager

def f(d, l):
    d[1] = '1'
    d['2'] = 2
    d[0.25] = None
    l.reverse()

if __name__ == '__main__':
    manager = Manager()

    d = manager.dict()
    l = manager.list(range(10))

    p = Process(target=f, args=(d, l))
    p.start()
    p.join()

    print d
    print l

<强>输出:

bash-4.3$ python -i foo.py 
{0.25: None, 1: '1', '2': 2}
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> 

注意:请注意您共享和附加到Process课程的主题类型,因为您可能会遇到酸洗问题。请参阅:Python multiprocessing pickling error