(Jul-30-2019, 10:31 AM)Larz60+ Wrote: Please do not link to another forum to ask a question.
Please show all details here.
Thank You
Ok, this is full question:
I have a simple producer/consumer python code. consumer is in main process, but for producer a class is defined, where the class makes a process for producer.
by a counter limit, main process stops the job, and terminates the producer. If termination signal is not handled, everything finish fine. but, when I added a graceful termination flag, termination signal is captured, but in a random behavior, sometimes termination is not done correctly, and I get buffer full exception (while buffer size is larger than task size). Is there any idea why this simple code has an nondeterministic behavior?
import multiprocessing
import signal
from queue import Full
buf = multiprocessing.Queue(maxsize=100)
class GracefulKiller:
kill_now = False
#------------------------------
def __init__(self):
self.kill_now = False
for signame in [signal.SIGTERM, signal.SIGQUIT, signal.SIGINT]:
signal.signal(signame, self.exit_tasks)
#------------------------------
def exit_tasks(self, signum, frame):
self.kill_now = True
process_name = multiprocessing.current_process().name
print("Process {} captured termination signal:{}.".format(process_name, signum,))
class num_source():
prc = None
buf2 = None
#------------------------------------------
def __init__(self, buf):
self.buf2 = buf
self.prc = multiprocessing.Process( target=self.__producer_procces__, args=(self.buf2, ))
self.prc.daemon = True
self.prc.start()
#------------------------------------------
def read_num(self):
return self.buf2.get(block=True, timeout=60)
#------------------------------------------
def terminate_request(self):
print("Termination of process requested.")
self.prc.terminate()
self.prc.join(10)
if self.prc.is_alive():
print("process did NOT join")
else:
print("process joined")
#------------------------------------------
def __producer_procces__(self, buf3,):
killer = GracefulKiller()
while True:
if killer.kill_now:
break;
num = 123 # or a random number
try:
buf3.put(num, block=True, timeout=10)
except Full:
print("Buffer is full, but should not!")
return
if __name__ == '__main__':
src_obj = num_source(buf)
cnt = 0
while True:
cnt += 1
num = src_obj.read_num()
print("{}-{}".format(cnt, num))
if (cnt == 50):
break;
src_obj.terminate_request()