繁体   English   中英

Python线程类调用另一个线程类(队列帮助)

[英]Python threaded class calls another threaded class (queue help)

我正在尝试使用X-Box控制器控制3轴打印机。 为了从x-box获取输入,我从martinohanlon https://github.com/martinohanlon/XboxController/blob/master/XboxController.py借来了代码,我还创建了可逐行读取文本文件的代码(G代码)移动打印机。

我希望能够使用X-Box控制器选择一个G代码文件并运行它,然后在打印机运行时继续监听取消按钮,以防万一打印出错。 控制器是一个线程类,而我的readGcode是一个线程类。

我遇到的问题是,当我使用控制器启动readGcode类时,直到该线程完成,我才能与控制器通信。

我的临时解决方案是使用控制器选择一个文件,然后将该文件路径传递给readGcode类。 在readGcode类中,它会继续尝试使用try块来打开文件,直到文件路径可接受为止,它都会失败。 然后,它会更改布尔值,使其跳过进一步的阅读,直到完成为止。

码:

import V2_Controller as Controller
import V2_ReadFile as Read
import time
import sys
# file daialogue
import tkinter as tk
from tkinter import filedialog

# when X is selected on the x-box controller 
def X(xValue):
    if not bool(xValue):
        try:
            f=selectfile()
            rf.setfilename(f)
        except:
            print("failed to select file")

def selectfile():
    try:
        root = tk.Tk()  # opens tkinter
        root.withdraw()  # closes the tkinter window
        return filedialog.askopenfilename()
    except Exception:
        print("no file")

# setup xbox controller
xboxCont = Controller.XboxController(controlCallBack, deadzone=30, 
scale=100, invertYAxis=True)
# init the readfile class
rf = Read.Readfile()

# set the custom function for pressing X
xboxCont.setupControlCallback(xboxCont.XboxControls.X, X)

try:
    # start the controller and readfile threads
    xboxCont.start()
    rf.start()

    xboxCont.join()
    rf.join()

    while True:
        time.sleep(1)

# Ctrl C
except KeyboardInterrupt:
    print("User cancelled")

# error
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

finally:
    # stop the controller
    xboxCont.stop()
    rf.stop()

V2_Readfile

# Main class for reading the script
class Readfile(threading.Thread):

    # supports all variables needed to read a script
    class readfile:
        fileselect = True
        linecount = 0
        currentline = 0
        commands = []

    # setup readfile class
    def __init__(self):
        # setup threading
        threading.Thread.__init__(self)
        # persist values
        self.running = False
        self.reading = False

    def setfilename(self,filename):
        self.filename = filename

    # called by the thread
    def run(self):
        self._start()

    # start reading
    def _start(self):
        self.running = True
        while self.running:
            time.sleep(1)
            if not self.reading:
                try:
                    self.startread()
                except:
                    pass

    def startread(self):
        try:
            with open(self.filename, "r") as f:  # read a local file
                f1 = f.readlines()
                # run through each line and extract the command from each line
                linecount = 0
                line = []
                for x in f1:
                    # read each line into an array
                    line.append(x.split(";")[0])
                    linecount += 1

                # Store the variables for later use
                self.readfile.linecount = linecount
                self.readfile.commands = line
                self.reading = True
        except Exception:
            pass

        i = 0
        while i < self.readfile.linecount and self.reading:
            self.readfile.currentline = i + 1
            self.readline(i)
            i += 1

        # the following stops the code from reading again
        self.reading = False
        self.filename = ""


    def readline(self,line):
        Sort.sortline(self.readfile.commands[line])

    # stops the controller
    def stop(self):
        self.running = False

您可以使用诸如threading.Event之类的同步原语。

为此,您需要像这样修改Readfile类:

from threading import Event


class Readfile(threading.Thread):

    # setup readfile class
    def __init__(self):
        # setup threading
        threading.Thread.__init__(self)
        # persist values
        self.running = False
        self.reading = False
        self.reading_file = Event()  # Initialize your event here it here

    def setfilename(self,filename):
        self.filename = filename
        self.reading_file.set()  # This awakens the reader

    def _start(self):
        self.running = True
        self.reading_file.wait()  # Thread will be stopped until readfilename is called
        self.startread()

另一个值得探讨的同步原语是queue.Queue 如果要处理多个文件名,这可能很有用。

您在问题中描述的模式称为“ 忙等待” ,应尽可能避免使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM