鱼C论坛

 找回密码
 立即注册
查看: 2228|回复: 4

Python多线程如何终止??

[复制链接]
发表于 2018-1-26 23:17:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
各位大神:
                小弟遇到问题求助,想用多线程编程,但是遇到问题是不能终止线程,
只能终止整个程序,我的想法是当按ButtonA时子线程Start,
内置函数不断循环,直到按下ButtonB为止。

本帖被以下淘专辑推荐:

  • · 百淘|主题: 11, 订阅: 0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-1-26 23:20:07 | 显示全部楼层
要不就是阻塞。
要不就用个变量在代码中判断。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-1-27 00:33:37 | 显示全部楼层
import threading
import time


class Job(threading.Thread):

    def __init__(self, *args, **kwargs):
        super(Job, self).__init__(*args, **kwargs)
        self.__flag = threading.Event()     # 用于暂停线程的标识
        self.__flag.set()       # 设置为True
        self.__running = threading.Event()      # 用于停止线程的标识
        self.__running.set()      # 将running设置为True

    def run(self):
        while self.__running.isSet():
            self.__flag.wait()      # 为True时立即返回, 为False时阻塞直到内部的标识位为True后返回
            print (time.time())
            time.sleep(1)

    def pause(self):
        print('pause')
        self.__flag.clear()     # 设置为False, 让线程阻塞

    def resume(self):
        print('resume')
        self.__flag.set()    # 设置为True, 让线程停止阻塞

    def stop(self):
        print('stop')
        self.__flag.set()       # 将线程从暂停状态恢复, 如何已经暂停的话
        self.__running.clear()        # 设置为False    

a = Job()
a.start()
time.sleep(3)
a.pause()
time.sleep(3)
a.resume()
time.sleep(3)
a.pause()
time.sleep(2)
a.stop()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-1-28 19:44:36 | 显示全部楼层

大神,你太棒了,太感谢你了,
我成功调试了,继承多线程类,构造函数利用标志位控制
暂停或停止。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-3-19 19:27:38 | 显示全部楼层
本帖最后由 yuexing 于 2018-3-19 19:30 编辑

# 不需要循环判断 可以立即终止线程,来终止线程的方法来着网络
import wx
import time
import threading, inspect, ctypes


def functest():

    def printex(str):
        while True:
            for dot in ['.', '..', '...']:
                yield print(str + ' ' + dot)

    generator = printex('函数')
    while True:
        next(generator)
        time.sleep(0.2)



class MyThread(threading.Thread):

    def __init__(self, func, args=(), kwargs=None):
        threading.Thread.__init__(self)

        if kwargs is None:
            kwargs = {}
        self.func = func
        self.args = args
        self.kwargs = kwargs

    def run(self):
        # print('子线程id', self.ident)
        self.func(*self.args, **self.kwargs)

    def stop_thread(self):
        if self.is_alive():
            self.__async_raise(self.ident, SystemExit)
        else:
            logger.info('线程没有存活')

    def __async_raise(self, tid, exctype):
        """raises the exception, performs cleanup if needed"""
        # print('被停止的线程id', tid)
        tid = ctypes.c_long(tid)
        if not inspect.isclass(exctype):
            exctype = type(exctype)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            # """if it returns a number greater than one, you're in trouble,
            # and you should call it again with exc=NULL to revert the effect"""
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
            raise SystemError("PyThreadState_SetAsyncExc failed")


class Frame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, size=(200, 100))

        panel = wx.Panel(self)

        boxsizer = wx.BoxSizer(wx.HORIZONTAL)
        self.startbutton = wx.Button(panel, label='启动按钮')
        self.endbutton = wx.Button(panel, label= '终止按钮')
        boxsizer.Add(self.startbutton, 1, wx.EXPAND)
        boxsizer.Add(self.endbutton, 1, wx.EXPAND)

        panel.SetSizer(boxsizer)



class App(wx.App):

    def OnInit(self):
        frame = Frame()
        frame.Show()

        frame.startbutton.Bind(wx.EVT_BUTTON, self.startprocess)
        frame.endbutton.Bind(wx.EVT_BUTTON, self.endprocess)
        return True

    def startprocess(self, event):
        print('启动事件启动了')
        self.thrd = MyThread(func=functest)
        self.thrd.start()

    def endprocess(self, event):
        print('终止事件启动了')
        self.thrd.stop_thread()



if __name__ == '__main__':
    app = App()
    print('app线程id: ', threading.get_ident())
    app.MainLoop()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-22 12:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表