Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 奇怪的线程行为_Python_Multithreading - Fatal编程技术网

Python 奇怪的线程行为

Python 奇怪的线程行为,python,multithreading,Python,Multithreading,我对python比较陌生,但对多线程软件不熟悉,所以我无法解释我看到的特定行为。我的程序非常简单:我监视linux命令“iostat”的输出,并在某些情况下执行一些操作。我的代码如下: class SysMonitor(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.isStopping = False self.ioprocess = [] def run(sel

我对python比较陌生,但对多线程软件不熟悉,所以我无法解释我看到的特定行为。我的程序非常简单:我监视linux命令“iostat”的输出,并在某些情况下执行一些操作。我的代码如下:

class SysMonitor(threading.Thread):

def __init__(self):
    threading.Thread.__init__(self)
    self.isStopping = False
    self.ioprocess = []

def run(self):
    self.ioprocess = subprocess.Popen(['/usr/bin/iostat', '-p', 'sda', '60'], stdout=subprocess.PIPE)
    p = self.ioprocess
    i = 0

    # Discard first output
    while (i < 11):
        p.stdout.readline()
        i = i + 1

    # Now keep on waiting on new output from iostat and then process it when it comes in
    while (not self.isStopping):
        select.select([p.stdout], [], [])

        # Don't process the last output if we are stopping
        if (self.isStopping):
            print 'Quitting, discarding last buffer:' + str(self.isStopping)
            continue

        # do some p.stdout.readline() and process the data

def stop(self):
    self.isStopping = True
    self.ioprocess.terminate()
我不明白的是,当我调用'stop'函数时,程序有时会崩溃,因为select被释放,因为EOF被写入标准输出缓冲区,但isStopping仍然是False。这怎么会发生

如果在线程外调用stop,可能会导致随机问题。因为当您调用stop时,线程可以是打印或选择等

只需在run方法的末尾移动终止符。然后将isStopping设置为True将正确地离开循环,然后终止进程

如果要等待,可以使用以下方法加入线程:

def stop(self):
    self.isStopping = True
    self.join()
如果在线程外调用stop,则可能会导致随机问题。因为当您调用stop时,线程可以是打印或选择等

只需在run方法的末尾移动终止符。然后将isStopping设置为True将正确地离开循环,然后终止进程

如果要等待,可以使用以下方法加入线程:

def stop(self):
    self.isStopping = True
    self.join()
基于您的评论,您可以在select.select中使用超时:

在上面,超时时间为5.0秒。我认为,这足够长,不至于重击系统,足够短,可以合理终止。更改以适合您的口味。

基于您的评论,您可以在选择中使用超时。选择:


在上面,超时时间为5.0秒。我认为,这足够长,不至于重击系统,足够短,可以合理终止。根据您的喜好进行更改。

如果目标是在应用程序结束时结束线程,则将线程设置为守护进程。

如果目标是在应用程序结束时结束线程,则将线程设置为守护进程。

运行terminate的问题是,程序不会在请求时立即终止,因为它可能会卡在select.select呼叫上。因此,在这种情况下,我可能会被困在等待程序终止长达1分钟的时间;os.kill0,signal.SIGPIPE在self.join之前。select的文档显示,如果收到信号,select将在信号接收时超时。这听起来不错,但不起作用。我将代码更改如下:ready,,=select.select[p.stdout],],[];如果self.isStopping或未准备好:继续,在stopself函数中,我有self.isStopping=True;os.kill0,signal.SIGPIPE;self.join信号到达select,但ready变量始终是一个文件描述符:[],因此我遇到了相同的问题。既然信号使select超时,ready不应该是一个空列表吗?我做错什么了吗?你不能在选择后做一个休息测试吗?然后不处理ready变量?你说的break测试是什么意思?运行terminate的问题是,当被请求时,程序不会立即终止,因为它可能在select.select调用中被卡住。因此,在这种情况下,我可能会被困在等待程序终止长达1分钟的时间;os.kill0,signal.SIGPIPE在self.join之前。select的文档显示,如果收到信号,select将在信号接收时超时。这听起来不错,但不起作用。我将代码更改如下:ready,,=select.select[p.stdout],],[];如果self.isStopping或未准备好:继续,在stopself函数中,我有self.isStopping=True;os.kill0,signal.SIGPIPE;self.join信号到达select,但ready变量始终是一个文件描述符:[],因此我遇到了相同的问题。既然信号使select超时,ready不应该是一个空列表吗?我做错什么了吗?你不能在选择后做一个休息测试吗?然后不处理ready变量?你说的break测试是什么意思?这会起作用,但我觉得这只是解决实际问题的一个办法:即isStopping标志在进程终止之前没有传输到线程,我不明白为什么。这会起作用,但我觉得这只是解决实际问题的一个办法真正的问题:也就是说,在进程终止之前,isStopping标志没有被传输到线程,我不明白为什么。