python线程通信_Python中线程之间的通信(不使用全局变量)

Let's say if we have a main thread which launches two threads for test modules - " test_a" and " test_b".

Both the test module threads maintain their state whether they are done performing test or if they encountered any error, warning or if they want to update some other information.

How main thread can get access to this information and act accordingly.

For example, if " test_a" raised an error flag; How "main" will know and stop rest of the tests before existing with error ?

One way to do this is using global variables but that gets very ugly.. Very soon.

解决方案

The obvious solution is to share some kind of mutable variable, by passing it in to the thread objects/functions at constructor/start.

The clean way to do this is to build a class with appropriate instance attributes. If you're using a threading.Thread subclass, instead of just a thread function, you can usually use the subclass itself as the place to stick those attributes. But I'll show it with a list just because it's shorter:

def test_a_func(thread_state):

# ...

thread_state[0] = my_error_state

# ...

def main_thread():

test_states = [None]

test_a = threading.Thread(target=test_a_func, args=(test_states,))

test_a.start()

You can (and usually want to) also pack a Lock or Condition into the mutable state object, so you can properly synchronize between main_thread and test_a.

(Another option is to use a queue.Queue, an os.pipe, etc. to pass information around, but you still need to get that queue or pipe to the child thread—which you do in the exact same way as above.)

However, it's worth considering whether you really need to do this. If you think of test_a and test_b as "jobs", rather than "thread functions", you can just execute those jobs on a pool, and let the pool handle passing results or errors back.

For example:

try:

with concurrent.futures.ThreadPoolExecutor(workers=2) as executor:

tests = [executor.submit(job) for job in (test_a, test_b)]

for test in concurrent.futures.as_completed(tests):

result = test.result()

except Exception as e:

# do stuff

Now, if the test_a function raises an exception, the main thread will get that exception—and, because that means exiting the with block, and all of the other jobs get cancelled and thrown away, and the worker threads shut down.

If you're using 2.5-3.1, you don't have concurrent.futures built in, but you can install the backport off PyPI, or you can rewrite things around multiprocessing.dummy.Pool. (It's slightly more complicated that way, because you have to create a sequence of jobs and call map_async to get back an iterator over AsyncResult objects… but really that's still pretty simple.)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值