队列/线程不影响主进程

时间:2017-05-29 15:56:34

标签: multithreading python-3.x queue

我正在尝试使用线程和排队(根据建议)暂停主进程。

我的程序基本上遍历图像,使用每次迭代的3秒时间循环打开和关闭它们。 我正在尝试使用线程来插入time.sleep(20),如果满足某个条件(x == True)。条件正在满足(通过print语句的输出显而易见),但time.sleep(20)不影响主进程。 我打算用更复杂的过程来替换time.sleep(20)但是为了简单起见,我在这里使用它。

import time
import subprocess
import pickle
import keyboard
import threading
from threading import Thread
import multiprocessing
import queue
import time

with open('C:\\Users\Moondra\\Bioteck.pickle', 'rb') as file:
    bio = pickle.load(file)





q = queue.LifoQueue(0)


def keyboard_press():    # This is just receiving boolean values based on key presses
    while True:
        q.put(keyboard.is_pressed('down'))
        x = q.get()
        print(x)
        if x == True:
           time.sleep(20)



t = Thread(target = keyboard_press, args= ())
t.start()


if __name__ == "__main__":

    for i in bio[:5]:
        p = subprocess.Popen(["C:\Program Files\IrfanView\i_view64.exe",'C:\\Users\Moondra\\Bioteck_charts\{}.png'.format(i)])

        time.sleep(3)
        p.kill()

那么为什么我的主题不会影响我的主要流程呢?

谢谢。

更新

所以我似乎必须使用标志并在我的函数中使用flag作为全局变量。我想避免使用global,但如果没有在我的函数中全局化flag,它就无法正常工作。

其次,我不知道如何重启线程。 一旦线程将flag返回为false,则线程排序就会停止。 我尝试使用t.start再次启动该线程,但我收到错误: RuntimeError: threads can only be started once

这是更新的代码:

def keyboard_press():
    while True:
        global flag
        q.put(keyboard.is_pressed('down'))
        x = q.get()
        print(x)
        if x == True:
           flag = False
           #print('keyboard_flag is',flag)
           return  flag





if __name__ == "__main__":
    flag = True
    q = queue.LifoQueue(0)
    t = Thread(target = keyboard_press, args= ())
    t.start()


    for i in bio[:5]:
        p = subprocess.Popen(["C:\Program Files\IrfanView\i_view64.exe",'C:\\Users\Moondra\\Bioteck_charts\{}.png'.format(i)])
        time.sleep(3)
        print ('flag is',flag)
        if flag == True:

            p.kill()

        else:
            time.sleep(20)
            p.kill()
            flag = True
            #t.start()  #doesn't seem to work.

1 个答案:

答案 0 :(得分:1)

  

为什么我的主题不影响我的主要流程?

因为您没有编写任何可能影响主进程的keyboard_press()线程执行的代码。

看起来您正在尝试创建一个每三秒显示一个图像的幻灯片,并且当某人按下某个键时您希望它暂停20秒。是吗?

所以,你有一个运行幻灯片放映的线程(主线程),你有另一个线程轮询键盘,但是你的两个线程不会相互通信。

您在键盘线程中调用time.sleep(20)。但这只会暂停键盘线程。它对主线程没有任何作用。

你需要的是键盘线程设置一个变量,主线程在从三秒钟休眠后唤醒它。主线程可以查看变量,看看是否已经请求了更长的睡眠,如果是,请再睡几秒钟。

当然,在较长时间的睡眠之后,您将需要主线程重新设置变量,以便在第一次触摸键盘后它不会始终睡眠20秒。

P.S。:我不是Python专家。我知道在其他编程环境(例如Java)中,您还必须担心“内存可见性”。也就是说,当一个线程更改变量时,无法保证何时(如果有的话)某个其他线程会看到更改...

...除非,线程在访问变量时使用某种同步

根据我所读到的内容(它在互联网上!必须是真的!),Python现在没有这个问题,或者它最近没有出现这个问题。我不确定是哪一个。

如果内存一致性确实存在问题,那么当您访问共享变量时,您将不得不使用mutex,否则您将不得不通过某种同步对象(例如,一个queue