Python time.sleep - never wake up

I think this will be one of those simple problems when you see, but it puzzled me.

[ STOP PRESS: I was right. Solution found. See Answers. ]

I am using the Python unittest framework to test a multi-threaded application. It's nice and straight forward - I have 5 workflows that control the overall queue, and one manufacturers flow that makes work items for them. Projector manufacturer starts up with a test case.

In this test, only one task is queued. The processing that he does, which is in the test, is just a stub for real processing, so the worker thread performs a 5 second sleep to simulate elapsed time before the task is actually completed, and the thread will be ready to perform another task.

To the code snippet:

logging.info("Sleep starting") time.sleep(5) logging.info("Waking up") 

Now the weird part. I see the Start Sleep Sleep message, but not the Awakening message. The program is blocked and does not respond to keyboard interruption (CTRL + C). CPU utilization is very low.

I see the same problem on Windows and Ubuntu (Python 2.6.2).

I thought about the exception happening and hiding, so I add "print 1/0" between the first and second lines - I see that the error "Debugger by zero" is raised. I move it after sleep and I never see a message.

I realized: “Well, maybe another thread is trying to register something very large at the same time, and it is still buffering. What is it doing?”

Well, at this point, the test returned to unittest, where it pauses the thread waiting to begin work before testing the state of the system.

  logging.info("Test sleep starting") time.sleep(0.25) logging.info("Test waking up") 

Wow, that looks familiar. It freezes the same way! The first log message appears, the second - no.

I recently made a significant alteration of the block, so I can’t say that “I didn’t touch anything”, but I don’t see anything unpleasant in my changes.

Suspicious areas:

  • I turn on the use of Threading.Lock (because I don’t know how to talk about GIL security, so I stick to what I know. I don’t see anything “dead” in relation to my code.

    / li>
  • I am new to the unitest Python framework. Is there something he does with log redirection or similar that can mimic these symptoms?

  • No, I did not replace the non-standard time module!

What would prevent a thread from waking up? What else did I miss?

+4
source share
2 answers

Sigh.

Worker No. 1 slept and then woke up. Then it will log an awakening message and is blocked. Only one thread can register at a time.

UnitTest Thread slept and woke up later. Then it will log an awakening message and is blocked. Only one thread can register at a time.

"Work-thread-previously-mentioned-in-question # 2" quietly finished processing the PRELIMINARY element in the queue, while the first workflow was sleeping. He hit the magazine. One of the parameters was the object, and str () was implicitly called. The str () function on this object had an error; he came to a standstill when he turned to some of his data members. A deadlock occurred during processing by the registration function, thereby retaining the blocking of the log stream and making it look like other threads never woke up.

The division by zero test did not affect, because the result was a log attempt.

+5
source

On linux, try changing the I / O scheduler to "Fully Fair Queue" (CFQ).

 echo cfq > /sys/block/sda/queue/scheduler 
-3
source

Source: https://habr.com/ru/post/1302492/


All Articles