简体   繁体   中英

How to implement right threading execution order in python?

I recently started studying threads in python, and I ran into this problem: I need the "two" function to finish executing after executing the function one in the thread, but the join method does not work, apparently because of the while true loop in the third function. I tried using queue, but it didn't work either.

the code itself:

from threading import Thread,Event

def one():
    event.set()
    thr.join()
    for i in range(3):
        print('some print')
        time.sleep(1)

def two():
    t = Thread(target=one)
    t.start()
    #with t.join() here the program does not work at all, same thing with event.set()
    print('func two finished')

def three(callback, event):
    c = 0
    while True:
        c += 1
        time.sleep(1)
        print('func 3 is working')
        if c == 5:
            two()
        if event.is_set():
            callback(c)
            print('func 3 is stopped')
            break

def callback(t):
    print('callback ',t)

def thread(callback):
    global event, thr
    event = Event()
    thr = Thread(target=three, args=(callback, event,))
    thr.start()
    thr.join()

thread(callback)

current output:

func 3 is working
func 3 is working
func 3 is working
func 3 is working
func 3 is working
func two finished
callback  5
func 3 is stopped
some print
some print
some print

expected:

func 3 is working
func 3 is working
func 3 is working
func 3 is working
func 3 is working
callback  5
func 3 is stopped
some print
some print
some print
func two finished

After running the code I understand by "not working" you mean the program finished before all prints are printed. The reason is that you join the thr thread twice, one of them by the main thread. The sequence of return of join is not guaranteed. When the main thread finished, all threads created by the program also finish, so they terminated no matter what.

Same thing when setting the event, it makes the main thread exit and kill the remaining threads.

To do what you intend, you should wait for the one thread in the main thread.

from threading import Thread,Event

def one():
    event.set()
    thr.join()
    for i in range(3):
        print('some print')
        time.sleep(1)

def two():
    t = Thread(target=one)
    t.start()
    #with t.join() here the program does not work at all, same thing with event.set()
    print('func two finished')

def three(callback, event):
    c = 0
    while True:
        c += 1
        time.sleep(1)
        print('func 3 is working')
        if c == 5:
            two()
        if event.is_set():
            callback(c)
            print('func 3 is stopped')
            break

def callback(t):
    print('callback ',t)

def thread(callback):
    global event, thr
    event = Event()
    thr = Thread(target=three, args=(callback, event,))
    thr.start()
    thr.join()

thread(callback)

Note that as other said, this might be nice for learning purpesses but has to be modified if you want to actually use it in real life code.

The sequence you need is obtained by a small permutation of commands. But it is not clear why you need threads if everything is done sequentially.

from threading import Thread, Event
import time


def one(event):
    event.set()
    for i in range(3):
        print('some print')
        time.sleep(1)


def two(event):
    t = Thread(target=one, args=(event,))
    t.start()
    t.join()
    print('func two finished')


def three(event):
    c = 0
    while True:
        c += 1
        time.sleep(1)
        print('func 3 is working')
        if c == 5:
            callback(c)
            print('func 3 is stopped')
            two(event)
            break


def callback(t):
    print('callback ', t)


def thread():
    event = Event()
    thr = Thread(target=three, args=(event,))
    thr.start()


thread()

--------------------------------

func 3 is working
func 3 is working
func 3 is working
func 3 is working
func 3 is working
callback  5
func 3 is stopped
some print
some print
some print
func two finished

This is a comment, not an answer.


This makes no sense:

    t = Thread(target=one, args=(event,))
    t.start()
    t.join()

There's no point in starting a new thread if you aren't going to do something concurrently with the thread. Either do this,

    t = Thread(target=one, args=(event,))
    t.start()
    do_something_else_concurrently_with_thread_t(...)
    t.join()

Or just just call the function instead of creating a new thread to call it:

    one(event)

If you don't want concurrency, then you don't need threads.

Your program creates a deadlock if you un-comment that t.join() call in function two ;

  • The thr thread cannot finish until after the t thread has finished because the thr thread calls t.join() in function two .

  • The t thread cannot finish until after the thr thread has finished because the t thread calls thr.join() in function one .

Neither thread can finish until after the other thread finishes. Therefore, neither thread can ever finish.


Why does one join the thr thread?

def one():
    event.set()
    thr.join()           # What were you trying to do here?
    for i in range(3):
        print('some print')
        time.sleep(1)

Your program will give the output you wanted if you comment out that join call, and uncomment the t.join() call in function two .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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