我想在按下按钮时运行并杀死一个线程 [英] I want to run and kill a thread on a button press

查看:45
本文介绍了我想在按下按钮时运行并杀死一个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,它应该通过串行连接向 arduino 发送一些数据点,该程序将控制一些电机移动.我可以单独发送控制信号,也可以通过 txt 文件发送控制信号,该文件将重复运行,直到文件完成.在运行 txt 文件时,我希望能够像暂停或停止按钮一样退出循环.我认为最好的方法是通过我可以关闭的线程.我以前从未做过任何线程处理,我的初步尝试也没有奏效.这里是发送文件数据的函数.

I have a program that is supposed to send a few data points over a serial connection to an arduino which will control some motors to move. I can send the control signals individually as well as by txt file which will run repeatedly until the file is complete. While running a txt file, I want to be able to exit the loop like a pause or stop button. I think the best way to do that is via a thread that I can close. I have never done any threading before and my rudimentary attempts have not worked. Here is the function that sends the file data.

def send_file():
    # Global vars
    global moto1pos
    global motor2pos
    # Set Ready value
    global isready
    # Get File location
    program_file_name = file_list.get('active')
    file_path = "/home/evan/Documents/bar_text_files/"
    program_file = Path(file_path + program_file_name)
    file = open(program_file)
    pos1 = []
    pos2 = []
    speed1 = []
    speed2 = []
    accel1 = []
    accel2 = []
    for each in file:
        vals = each.split()
        pos1.append(int(vals[0]))
        pos2.append(int(vals[1]))
        speed1.append(int(vals[2]))
        speed2.append(int(vals[3]))
        accel1.append(int(vals[4]))
        accel2.append(int(vals[5]))
    # Send file values
    try:
        while isready == 1:
            for i in range(len(pos1)):
                print("Step: " + str(i+1))
                data = struct.pack("!llhhhh", pos1[i], pos2[i], speed1[i], speed2[i], accel1[i], accel2[i])
                ser.write(data)

                try:
                    pos1time = abs(pos1[i]/speed1[i])
                except:
                    pos1time = 0
                try:
                    pos2time = abs(pos2[i]/speed2[i])
                except:
                    pos2time = 0
            time_array = (pos1time, pos2time)
            time.sleep(max(time_array))
            motor1pos = ser.readline()
            motor2pos = ser.readline()
            if i < (len(pos1)-1):
                isready = ord(ser.read(1))
            else:
                isready = 0
except:
    print("Error: data not sent. Check serial port is open")

这是我希望使用 sendfile 命令工作的线程命令.

Here is the threading command which I want the sendfile command to work from.

def thread():
    try:
        global isready
        isready = 1
        t = threading.Thread(name='sending_data', target=command)
        t.start()
    except:
        print("Threading Error: you don't know what you are doing")

这是我希望线程被杀死的停止函数:

And here is the stop function I want the thread to be killed by:

def stop():
    try:
        global isready
        isready = 0
        t.kill()
    except:
        print("Error: thread wasn't killed")

我知道你不应该杀死一个线程,但数据并不是很重要.更重要的是在发生故障之前停止电机.

I know you aren't supposed to kill a thread but the data isn't very important. Whats more important is to stop the motors before something breaks.

tkinter 中的按钮是:

The button in tkinter is:

run_file_butt = tk.Button(master = file_frame, text = "Run File", command = thread)

当我单击按钮时,程序会运行,但停止功能不会停止运动.

When I click the button, the program runs but the stop function does nothing to stop the motion.

推荐答案

由于我对线程的简单理解以及我使用线程的独特环境,我的答案很简单.我没有以我希望的方式终止线程,而是在 send_file 函数的发送行中添加了另一个条件语句.

The answer I have gone with is simple due to my simple understanding of threading and unique circumstances with which I am using the threading. Instead of terminating the thread in a way I was hoping, I added another conditional statement to the sending line of the send_file function.

    while isready == 1:
        for i in range(len(pos1)):
            if motorstop == False:
                print("Step: " + str(i+1))
                #data = struct.pack('!llllhhhhhhhh', pos1[i], pos2[i], pos3[i], pos4[i], speed1[i], speed2[i], speed3[i], speed[4], accel1[i], accel2[i], accel3[i], accel4[i])
                data = struct.pack("!llhhhh", pos1[i], pos2[i], speed1[i], speed2[i], accel1[i], accel2[i])
                ser.write(data)
            else:
                isready = 0
                break

并且我已将我的 stop() 函数更新为以下内容:

and I have updated my stop() func to the following:

def stop():
    try:
        global motorstop
        global t
        motorstop = True
        t.join()
    except:
        print("Error: thread wasn't killed")

我不确定它是如何工作的,但它比@stovefl 提到的要简单得多.

I'm not exactly sure how it works but it is much simpler than what was mentioned by @stovefl.

使用这段代码,由于函数大部分只是休眠,它可以运行但不会发送任何新信息,然后在下一次迭代后将 .join() .

With this code, since the function is mostly just sleeping, it can run but it won't send any new information and then will .join() after the next iteration.

这篇关于我想在按下按钮时运行并杀死一个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆