SHARED RESOURCE • Race condition: T1: RW T2: RW T1+T2: RRWW • Use lock → Thread-safe: T1+T2: (RW) (RW) • But lock causes worse performance and deadlock. • Which is the hard part. 9
WHY .TASK_DONE? • It’s for .join. • When the counter goes zero, it will notify the threads which are waiting. • It’s implemented by threading.Condition. 14
BROADCAST SIGNAL TO SUB-THREAD • Set a global flag when get signal. • Let thread read it before each task. • No, you can’t kill non-daemonic thread. • Just can’t do so. 23
BROADCAST SIGNAL TO SUB-THREAD • Set a global flag when get signal. • Let thread read it before each task. • No, you can’t kill non-daemonic thread. • Just can’t do so. • It’s Python. 23
BROADCAST SIGNAL TO SUB-PROCESS • Just broadcast the signal to sub-processes. • Start with register signal handler: signal(SIGINT, _handle_to_term_signal) 24
JUST THREAD IT OUT • Or process it out. • Let main thread exit earlier. (Looks faster!) • Let main thread keep dispatching tasks. • “Async” • And fix some stupid behavior. (I meant atexit with multiprocessing.Pool.) 27
CONCLUSION • Avoid shared resource — or just use producer-consumer pattern. • Signals only go main thread. • Just thread it out. • Collect your result smarter. 32
CONCLUSION • Avoid shared resource — or just use producer-consumer pattern. • Signals only go main thread. • Just thread it out. • Collect your result smarter. • Monitor and benchmark your code. 32