Search code examples
pythonpython-3.xmultithreadingpython-multithreading

Python thread runs only once instead of running continuously. All threads should run continuously


I'm trying to implement threading but it only runs once instead of running continuously.

This is where I'm creating the threads and calling the functions :

thread_list = []
for ldx, stream in enumerate(input_stream_list):
   thread = threading.Thread(target=frame_thread, args=(stream, "stream{0}".format(ldx), ldx))
   thread_list.append(thread)

for thread in thread_list:
   thread.start()

retrieve_thread_list = []
for kdx, streamk in enumerate(input_stream_list):
   threadk = threading.Thread(target=retrieve_thread, args=(streamk, kdx))
   retrieve_thread_list.append(threadk)

for threadk in retrieve_thread_list:
   threadk.start()

for thread in thread_list:
   thread.join()

for threadk in retrieve_thread_list:
   threadk.join()

while True:
   pass

This is the implementation of the frame_thread :-


def frame_thread(url, dire, i):
    global camera_reconnection, video_retrieval_status
    cap = cv2.VideoCapture(url)
    ret = cap.set(3, 768)
    ret = cap.set(4, 432)
    if not os.path.exists(name + dire):
        os.mkdir(name + dire)
    for x in os.listdir(name+dire):
        items[i].append(x)
    items[i].sort()
    for k in items[i]:
        q2[i].append(os.path.join(name+dire, k))
    while cap.isOpened():
        if camera_reconnection[i]:
            cap = cv2.VideoCapture(url)
            last_frame[i] = False
            camera_reconnection[i] = False
        if last_frame[i] is False:
            start_time = time.time()
            ret, frame = cap.read()
            if ret:
                video_file = os.path.join(name + dire, str(time.strftime('%H %M %S'))+".avi")
                q2[i].append(video_file)
                if len(q2[i]) > int(video_save):
                    data = q2[i].popleft()
                    os.remove(data)
                video_writer = cv2.VideoWriter(video_file, video_codec, fps, (int(cap.get(3)), int(cap.get(4))))
                while(int(time.time() - start_time)) < video_duration:
                    ret, frame = cap.read()
                    if not ret:
                        last_frame[i] = True
                        video_writer.release()
                        cv2.destroyAllWindows()
                        break
                    video_writer.write(frame)
                video_writer.release()
                if(video_retrieval_status[i] == VIDEO_LIST_RETRIEVAL_SPECIFIC_START):
                    video_retrieval_status[i] = VIDEO_LIST_RETRIEVAL_SPECIFIC_READY

And Here's my retrieve_thread function : -

def retrieve_thread(streamk, k):
    global video_retrieval_status
    print("dbg0", flush=True)
    if(video_retrieval_status[k] == NO_RETRIEVAL):
        print("dbg1", flush=True)
    else:
        print("dbg2", flush=True)

        if (video_retrieval_status[k] == VIDEO_LIST_RETRIEVAL_SPECIFIC_READY):
            print("dbg3", flush=True)
            post_storage_retrieval_specific(k)
            print("dbg4", flush=True)
            video_retrieval_status[k] = NO_RETRIEVAL

The threadk - retrieve_thread is only executing once. What am I doing wrong?


Solution

  • retrieve_thread() does not have any loop. Once the function ends, the thread will close.

    Try adding a while loop:

    import time
    def retrieve_thread(streamk, k):
        global video_retrieval_status
        while True:  # Any condition to continue the thread execution
            time.sleep(5)  # Make sure the polling isn't too frequent
            print("dbg0", flush=True)
            if(video_retrieval_status[k] == NO_RETRIEVAL):
                print("dbg1", flush=True)
            else:
                print("dbg2", flush=True)
            
                if (video_retrieval_status[k] == VIDEO_LIST_RETRIEVAL_SPECIFIC_READY):
                    print("dbg3", flush=True)
                    post_storage_retrieval_specific(k)
                    print("dbg4", flush=True)
                    video_retrieval_status[k] = NO_RETRIEVAL