理想线程结构题(涉及多线程通信) [英] ideal thread structure question (involves multiple thread communication)

查看:67
本文介绍了理想线程结构题(涉及多线程通信)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个侦听声音事件的应用程序(使用通过 Open Sound Control 传入的消息),然后根据这些事件暂停或恢复程序执行.我的结构大部分时间都在工作,但总是在主循环中爆炸,所以我猜这是一个线程问题.这是我所谈论内容的通用简化版本:

I'm writing an application that listens for sound events (using messages passed in with Open Sound Control), and then based on those events pauses or resumes program execution. My structure works most of the time but always bombs out in the main loop, so I'm guessing it's a thread issue. Here's a generic, simplified version of what I'm talking about:

import time, threading

class Loop():
    aborted = False

    def __init__(self):
        message = threading.Thread(target=self.message, args=((0),))
        message.start()

        loop = threading.Thread(target=self.loop)
        loop.start()


    def message(self,val):

        if val > 1:
            if not self.aborted:
                self.aborted = True
                # do some socket communication            
            else:
                self.aborted = False
                # do some socket communication


    def loop(self):
        cnt = 0

        while True:
            print cnt
            if self.aborted:
                while self.aborted:
                    print "waiting"
                    time.sleep(.1);
            cnt += 1


class FakeListener():
    def __init__(self,loop):
        self.loop = loop
        listener = threading.Thread(target=self.listener)
        listener.start()

    def listener(self):
        while True:
            loop.message(2)
            time.sleep(1)



if __name__ == '__main__':

    loop = Loop()

    #fake listener standing in for the real OSC event listener
    listener = FakeListener(loop)

当然,这个简单的代码似乎工作得很好,所以它显然没有完全说明我的真实代码,但你明白了.此处未包括的还有一个事实,即在每个循环暂停和恢复(通过设置 aborted=True/False)会导致某些套接字通信也涉及线程.

Of course, this simple code seems to work great, so it's clearly not fully illustrating my real code, but you get the idea. What isn't included here is also the fact that on each loop pause and resume (by setting aborted=True/False) results in some socket communication which also involves threads.

在我的代码中总是发生的是,主循环在声音事件之后并不总是从它停止的地方开始.它适用于许多事件,但最终它只是不回答.

What always happens in my code is that the main loop doesn't always pickup where it left off after a sound event. It will work for a number of events but then eventually it just doesn't answer.

对于如何在线程之间构建这种通信有什么建议吗?

Any suggestions for how to structure this kind of communication amongst threads?

更新:

好的,我想我明白了.这是一个似乎有效的修改.有一个侦听器线程会定期将值放入 Queue 对象中.有一个检查器线程会不断检查队列以查找值,一旦它看到它就会将一个布尔值设置为其相反的状态.该布尔值控制循环线程是继续还是等待.

ok, i think i've got it. here's a modification that seems to work. there's a listener thread that periodically puts a value into a Queue object. there's a checker thread that keeps checking the queue looking for the value, and once it sees it sets a boolean to its opposite state. that boolean value controls whether the loop thread continues or waits.

不过,我不完全确定 q.task_done() 函数在这里做什么.

i'm not entirely sure what the q.task_done() function is doing here, though.

import time, threading
import Queue

q = Queue.Queue(maxsize = 0)

class Loop():
    aborted = False

    def __init__(self):
        checker = threading.Thread(target=self.checker)
        checker.setDaemon(True)
        checker.start()

        loop = threading.Thread(target=self.loop)
        loop.start()


    def checker(self):
        while True:
            if q.get() == 2:
                q.task_done()
                if not self.aborted:
                    self.aborted = True
                else:
                    self.aborted = False


    def loop(self):
        cnt = 0

        while cnt < 40:
            if self.aborted:
                while self.aborted:
                    print "waiting"
                    time.sleep(.1)
            print cnt
            cnt += 1
            time.sleep(.1)


class fakeListener():

    def __init__(self):
        listener = threading.Thread(target=self.listener)
        listener.setDaemon(True)
        listener.start()

    def listener(self):
        while True:
            q.put(2)
            time.sleep(1)



if __name__ == '__main__':

    #fake listener standing in for the real OSC event listener
    listener = fakeListener()

    loop = Loop()

推荐答案

嗯.. 我不完全理解你的问题,但我会尽力解释我认为你需要解决什么问题.

Umm.. I don't completely understand your question but i'll do my best to explain what I think you need to fix your problems.

1) 你的 Loop.loop 函数的线程应该设置为守护线程,这样它就和你的主线程一起退出(这样你就不用每次想关闭程序时都杀掉 python 进程).为此,只需在调用线程的启动"函数之前放置 loop.setDaemon(True).

1) The thread of your Loop.loop function should be set as a daemon thread so that it exits with your main thread (so you don't have to kill the python process every time you want to shut down your program). To do this just put loop.setDaemon(True) before you call the thread's "start" function.

2) 线程间通信最简单、最可靠的方式是使用队列.On 线程会将一个项目放入该队列中,另一个线程将取出一个项目,对该项目执行某些操作,然后终止(或获得另一份工作)

2)The most simple and fail-proof way to communicate between threads is with a Queue. On thread will put an item in that Queue and another thread will take an item out, do something with the item and then terminate (or get another job)

在python中,队列可以是从全局列表到python内置队列对象的任何东西.我推荐 python Queue 因为它是线程安全的并且易于使用.

In python a Queue can be anything from a global list to python's built-in Queue object. I recommend the python Queue because it is thread safe and easy to use.

这篇关于理想线程结构题(涉及多线程通信)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆