#import threading
import multiprocessing
import time
condition = True
finish_state = False
x = 0
all_processes = []
def operation_process(x):
#many operations with x value that if they take a long time will be closed because the other thread will set the boolean to True and close all open threads
time.sleep(20) #for example these operations with x take 20 seconds in this case
def finish_process(finish_state):
finish_state = True
time.sleep(5) #time to send the boolean that terminates all started threads
return finish_state
def main_process(condition, finish_state, x):
while condition == True:
#Create a new thread and fork the code()
#THIS IS THE LINE WHERE I AM SUPPOSED TO BE EXPECTING TO RECEIVE THE RETURN VALUE, AT THE CYCLE NUMBER IN WHICH THE FUNCTION finish_state() TIME HAS FINISHED...
#thr1 = threading.Thread(target=finish_process, args=(finish_state, ))
thr1 = multiprocessing.Thread(target=finish_process, args=(finish_state, ))
#thr2 = threading.Thread(target=operation_process, args=(x, ))
thr2 = multiprocessing.Thread(target=operation_process, args=(x, ))
x = x 1
print("cycle number: " str(x))
#Only in the first cycle
if(x == 1):
thr1.start()
thr2.start()
all_processes.append(thr1)
all_processes.append(thr2)
#print(threading.activeCount()) #to list open threads
print(multiprocessing.active_children()) #to list open subprocesses
if(finish_state == True):
print("loop ends!")
for process in all_processes:
process.terminate()
condition = False
main_process(condition, finish_state, x)
print("continue the code with other things after all threads/processes except the main one were closed with the loop that started them... ")
如何接收執行緒內部finish_state = True函式回傳的值?finish_process()
目標是主執行緒呼叫main_process()包含模擬do-while回圈的回圈的函式,并且在該回圈內僅在該回圈的第一個回圈期間(即,當變數x = 1)創建執行緒,并且想法就是do-while回圈一直重復,直到執行緒回傳值finish_state = True,主執行緒關閉,因為變數finish_state不是False。
但問題是我需要 `` 只在第一個回圈上運行,否則每次迭代都會創建一個新執行緒,但同時我必須等待那個執行緒在某個時候回傳給我 finish_state = True
我決定將執行緒更改為子行程,因為它更容易殺死它們,因為即使執行緒共享變數,我也沒有找到選擇性地殺死它們的方法,所以使用terminate()方法來殺死行程。我不確定這是否是最好的方法,因為無論如何我需要以某種方式使作為變數的信號finish_state到達行程或主執行緒,以便它決定是否應該關閉所有執行緒、行程或執行緒,減去自身。
編輯:當我嘗試使用 Frank Yellin 的代碼時,這給了我控制臺中的錯誤:
Traceback (most recent call last):
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "<string>", line 1, in <module>
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 116, in spawn_main
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
exitcode = _main(fd, parent_sentinel)
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 125, in _main
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 125, in _main
prepare(preparation_data)
prepare(preparation_data)
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 236, in prepare
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 236, in prepare
_fixup_main_from_path(data['init_main_from_path'])
_fixup_main_from_path(data['init_main_from_path'])
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
main_content = runpy.run_path(main_path,
main_content = runpy.run_path(main_path,
File "C:\Users\Maty0\Anaconda3\lib\runpy.py", line 265, in run_path
File "C:\Users\Maty0\Anaconda3\lib\runpy.py", line 265, in run_path
return _run_module_code(code, init_globals, run_name,
return _run_module_code(code, init_globals, run_name,
File "C:\Users\Maty0\Anaconda3\lib\runpy.py", line 97, in _run_module_code
File "C:\Users\Maty0\Anaconda3\lib\runpy.py", line 97, in _run_module_code
_run_code(code, mod_globals, init_globals,
_run_code(code, mod_globals, init_globals,
File "C:\Users\Maty0\Anaconda3\lib\runpy.py", line 87, in _run_code
File "C:\Users\Maty0\Anaconda3\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
exec(code, run_globals)
File "C:\Users\Maty0\Desktop\P\Python\Threads\thread_way.py", line 36, in <module>
File "C:\Users\Maty0\Desktop\P\Python\Threads\thread_way.py", line 36, in <module>
main_process(finish_state)
main_process(finish_state)
File "C:\Users\Maty0\Desktop\P\Python\Threads\thread_way.py", line 26, in main_process
File "C:\Users\Maty0\Desktop\P\Python\Threads\thread_way.py", line 26, in main_process
thr1.start()
thr1.start()
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\process.py", line 121, in start
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\process.py", line 121, in start
self._popen = self._Popen(self)
self._popen = self._Popen(self)
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\context.py", line 224, in _Popen
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
return _default_context.get_context().Process._Popen(process_obj)
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\context.py", line 327, in _Popen
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\context.py", line 327, in _Popen
return Popen(process_obj)
return Popen(process_obj)
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\popen_spawn_win32.py", line 45, in __init__
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\popen_spawn_win32.py", line 45, in __init__
prep_data = spawn.get_preparation_data(process_obj._name)
prep_data = spawn.get_preparation_data(process_obj._name)
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 154, in get_preparation_data
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 154, in get_preparation_data
_check_not_importing_main()
_check_not_importing_main()
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 134, in _check_not_importing_main
File "C:\Users\Maty0\Anaconda3\lib\multiprocessing\spawn.py", line 134, in _check_not_importing_main
raise RuntimeError('''
raise RuntimeError('''
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
uj5u.com熱心網友回復:
我認為你完全錯了。我也不太清楚為什么你有全域變數,然后作為引數傳遞給函式,而不僅僅是區域變數。
無論如何,您正在尋找這樣的東西。你需要把finish_state變成一個事件,一個執行緒可以設定,其他執行緒可以觀察。
finish_state = multiprocessing.Event()
def operation_process(x):
# many operations with x value that if they take a long time will be closed because the other thread will set the boolean to True and close all open threads
time.sleep(20) # for example these operations with x take 20 seconds in this case
def finish_process(finish_state):
time.sleep(5)
finish_state.set()
def main_process(finish_state):
# Create a new thread and fork the code()
# THIS IS THE LINE WHERE I AM SUPPOSED TO BE EXPECTING TO RECEIVE THE RETURN VALUE, AT THE CYCLE NUMBER IN WHICH THE FUNCTION finish_state() TIME HAS FINISHED...
# thr1 = threading.Thread(target=finish_process, args=(finish_state, ))
thr1 = multiprocessing.Thread(target=finish_process, args=(finish_state,))
thr1.start()
thr2 = multiprocessing.Thread(target=operation_process, args=(0,))
thr2.start()
finish_state.wait()
for process in [thr1, thr2]:
process.terminate()
if __name__ == '__main__':
main_process(finish_state)
如果您想要每秒一次的狀態報告,直到完成:
while not finish_state.wait(timeout=1):
# .wait() returns False if this times out:
... print status report ....
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/412300.html
標籤:
