How to end a child thread that is in a blocking state after receiving Ctrl+C in python multithread

in python multithreading, only the main thread can receive the signal and cannot use join blocking.
so how does the main thread end the child thread in the blocking state after receiving the signal

the following code child threads receive_task1 are blocking in the os.read () (receiving serial port data, but the serial port does not receive data) function. Is there any way to let the os.read () function exit?

if you use os.read () in the main thread, by default you can use Ctrl+C to interrupt. What"s the best way to do this now?

import os
import signal
import threading
import time

def test(signum, frame):
    print("\nreceived sig %d" % (signum))
    print("how to make os.read(...) in rcv_task1 thread stop? ")
    print("except use sys.exit(1)")

def receive_task1():
    fd = os.open("/dev/ttyUSB1", os.O_RDWR)
    os.read(fd, 10)
    print("receive thread end")

signal.signal(signal.SIGINT, test)

rcv_task1 = threading.Thread(target=receive_task1)
rcv_task1.setDaemon(True)
rcv_task1.start()
while(1):
    time.sleep(1)

I have only learned the socket library, but I am not familiar with the os library. According to my current knowledge, there are two solutions:
1, change to multi-process mode, and then terminate the child process in the main process;
2, set the file descriptor fd in the child thread to non-blocking mode, just check that there is an os.set_blocking (fd, blocking) function available in the os library. The
code is roughly as follows (I haven't tested it under Linux):

import os
import signal
import threading
import time

keep_running = True

def my_handler(signum, frame):
    """"""
    global keep_running
    print('received sig {}'.format(signum))
    keep_running = False -sharp
    print('thre thread end')

def task():
    """"""
    fd = os.open('example.txt', os.O_RDWR) -sharp
    os.set_blocking(fd, blocking=False) -sharpfd
    while keep_running: -sharp==
        recv = os.read(fd, 10)
        time.sleep(0.1)

signal.signal(signal.SIGINT, my_handler) -sharpCTRL+C
thre = threading.Thread(target=task)
thre.start()
while True:
    time.sleep(1)

first of all, I didn't really look at your code (because I intend only to give you the right ideas).
then, here is the answer to this question:

  1. relationship between signal and thread:

    Pyhon Docs:

    18.8.1.2. Signals and threads

    Python signal handlers are always executed in the main Python thread, even if the signal was received in another thread. This means that signals can't be used as a means of inter-thread communication. You can use the synchronization primitives from the threading module instead.
    Besides, only the main thread is allowed to set a new signal handler.
    (in a nutshell, the signal is only processed in the main thread)

  2. how do I exit the child thread when I receive the signal?
    the state of the child thread can only be controlled by the child process itself. other threads have only two operations available to it ( .join and .is _ alive ).
    but threads can communicate (scheduling). Through the queue.Queue child thread, you can receive the behavior that other threads expect it to do.
    for example, after the main thread receives the Ctrl+C (SIGINT), places the 'quit' message in the QUEUE, and then the child thread gets the' quit' message from the QUEUE, it has to do its own exit action.
    so to do this, you need to write threads very carefully (if your thread has the possibility of blocking and you want the thread to run in the background all the time):

    • you need to implement the thread exit mechanism!
    • you need to make sure that the thread doesn't block (otherwise it won't know it should quit)!
    • then polls the background thread at a specific point to determine whether it needs to exit.

if you need to implement a thread that runs in the background all the time, then you should not write a thread as a function! So my advice is to write a class-level thread. In this way, you can separate the exit mechanism from the loop mechanism.
because of the first point above, there is no "general" solution for writing class-level threads that may block: socket has a non-blocking way to set socket, and queue.Queue has its own way to set non-blocking.
(see APUE for a chapter on what is blocking IO, and what is non-blocking IO,. )

finally, I provide my CSDN blog: [Python] [Multithreading] Python multithreaded Development Guide | completion: 20%
as of 2019-02-27, the article was 20% complete, but all of the above can be found on the blog.

Menu