多线程Python退出

时间:2014-05-21 11:31:33

标签: python multithreading

我有一个API,我想创建一个客户端来从interne发送/ recv数据,所以我使用了一个线程,所以我的api因为阻塞命令而不会被冻结。在我的线程中,我在写/读数据时循环。问题是1循环程序退出后我不知道为什么。

这是我的线程类

class WorkerThread(Thread):
"""Worker Thread Class."""
def __init__(self):
    """Init Worker Thread Class."""
    Thread.__init__(self)
    self._want_abort = 0
    # This starts the thread running on creation, but you could
    # also make the GUI thread responsible for calling this
    self.start()

def run(self):
    while(1):
        if self._want_abort:
           # Use a result of None to acknowledge the abort (of
            # course you can use whatever you'd like or even
            # a separate event type)
            wx.PostEvent(ResultEvent(None))
            return
        Socket_ID=OPEN_CLIENT(str('184.106.153.149'), 3000, 80, SOCKET_STREAM)

        WRITE(Socket_ID, 123, len(123))
        time.sleep(0.5)
        test = READ(Socket_ID)
        if 'on' in test:
            SET_IO(1,1)
        if 'off' in test:
            SET_IO(1,0)

        time.sleep(1)
        CLOSE(Socket_ID)
        time.sleep(10)


def abort(self):
    """abort worker thread."""
    # Method for use by main thread to signal an abort
    self._want_abort = 1

我在触发复选框事件后将其称为我的主要内容:

def receive_data(self, event):
        if self.get_cmd == 0:

            self.get_cmd = 1
            self.worker = WorkerThread(self)

        else:
            self.get_cmd = 0
            self.worker.abort()

我从这里看到了Thread类:http://wiki.wxpython.org/LongRunningTasks

如果我使用它,客户端服务器之间的I / O是正常的,但API正在冻结

def receive_data(self, event):
        if self.get_cmd == 0:

            self.get_cmd = 1
            self.worker = WorkerThread(self)
            self.worker.join()

        else:
            self.get_cmd = 0
            self.worker.abort()

好的,这是另一个循环3-4次然后它粉碎的approch:

def receive_data(self, event):

        if self.get_cmd == 0:
            self.thingspeak = threading.Thread(target=recv_data_thingspeak, args = (self.talkback_field.GetValue(),))
            self.thingspeak.start()

        else:
            self.receive_bt.SetValue(True)



def recv_data_thingspeak(queue):

    Socket_ID =OPEN_CLIENT(str('184.106.153.149'), 3000, 80, SOCKET_TYPE_STREAM)
    while(1):

        request = "GET /apps/thinghttp/send_request?api_key=" + queue + " HTTP/1.1\r\n"
        request += "Host: api.thingspeak.com\r\n\r\n"

        WRITE(Socket_ID, 123, len(123))
        time.sleep(1)
        test = READ(Socket_ID)
        if 'on' in test:
            SET_IO(1,1)
        if 'off' in test:
            SET_IO(1,0)

        time.sleep(10)

    CLOSE(Socket_ID)

1 个答案:

答案 0 :(得分:1)

多线程可能令人困惑。例如,在第一批代码中,父htread正在设置(workerthread)._ want_abort。但是,此标志仅存在于父项中,而不存在于worker中,因此这种类型的信令不起作用。

通常,多线程程序通过在父级中创建Queue(或Event等)来工作,然后创建一组工作者 - 为每个工作者提供对队列的引用。然后,当父级或工作程序使用队列时,所有线程都会看到结果。你不能用列表或其他“原始”对象来做这件事;队列具有魔力,因此多个线程可以修改它,其他线程将被通知

在下面我们开始三个工人,等一下,然后发出信号让他们全部死亡。我们通过在父级中创建Event并与每个工作人员共享来实现此目的。

import time
from threading import *

class WorkerThread(Thread):
    def __init__(self, die_flag, *args, **kw):
        super(WorkerThread,self).__init__(*args, **kw)
        self.die_flag = die_flag

    def run(self):
        for num in range(3):
            if self.die_flag.is_set():
                print "{}: bye".format(
                    current_thread().name
                    )
                return
            print "{}: num={}".format(
                current_thread().name, num,
                )
            time.sleep(1)

flag = Event()

print 'STARTING THREADS'
WorkerThread(name='whiskey', die_flag=flag).start()
WorkerThread(name='syrup', die_flag=flag).start()
WorkerThread(name='bitters', die_flag=flag).start()

print '\nRELAXING'
time.sleep(2)

print '\nTELL WORKERS TO DIE'
flag.set()

print '\nWAITING FOR WORKERS'
for thread in enumerate():
    if thread != current_thread():
        print thread.name,':',
        thread.join()
        print 'joined'

print '\nDONE'

示例运行:

STARTING THREADS
whiskey: num=0
syrup: num=0
bitters: num=0

RELAXING
syrup: num=1
whiskey: num=1
bitters: num=1
syrup: num=2
bitters: num=2

TELL WORKERS TO DIE
 whiskey: num=2

WAITING FOR WORKERS
whiskey : joined
bitters : joined
syrup : joined

DONE