ZijingMao / labstreaminglayer

Automatically exported from code.google.com/p/labstreaminglayer
0 stars 0 forks source link

blocking call to pull_sample claiming Python's GIL forever when no data available #12

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

1. Create a simple receiving application like described in the example: 
https://code.google.com/p/labstreaminglayer/source/browse/LSL/liblsl-Python/exam
ples/ReceiveData.py

2. Don't write the sending counterpart

3. Start your receiving application

What is the expected output? What do you see instead?

The application will block on `inlet.pull_sample()`, which is fine. But It will 
not be possible to stop the application via CTRL-C (Linux). Compare it with 
other blocking network operations in Python's standard library, where it is 
always possible to kill the application with CTRL-C, even when it is blocking 
on I/O.

I haven't looked into the code, but I assume that the underlying wrapper code 
for C/C++ is claiming Python's Global Interpreter Lock (GIL) and never 
releasing it, while blocking on `pull_sample`. An easy way to test this 
assumption would be, to write a threaded application, where the first thread 
just prints something every second and the second thread receives data. If the 
second one blocks and claims the GIL forever, the first thread should stop 
printing numbers.

What version of the product are you using? On what operating system?

Current head from hg.

Please provide any additional information below.

Original issue reported on code.google.com by bastian....@gmail.com on 15 May 2014 at 9:56

GoogleCodeExporter commented 8 years ago
You're right -- a reasonable fix in pylsl would be to have an internal Python 
loop that calls the blocking system function with shorter timeouts. The only 
issue with that is that too short timeouts will noticable CPU load. Better 
suggestions?

A quick workaround in the application would be to use a sufficiently short 
timeout (e.g., 1/30 second in a real-time application) and use a loop around it 
that checks whether the return value was nonzero (if it's zero the timeout 
expired and no data was available).

Original comment by christia...@gmail.com on 1 Aug 2014 at 10:03