The event waiting thread has mysteriously long delay in the next case.
Could someone tell me the cause of delay or the way to reduce the
dalay?
LONG DELAY CASE(C++ app. like below) :
1. A thread, called result collector, creates a work thread with
PTHREAD_CREATED_DETACHED attribute by calling pthread_create().
2. The result collector waits for the worker by calling
pthread_cond_timedwait() with 1 second timeout value.
3. The worker does short task(usually under 10 ms) and call
pthread_cond_signal() to wake up the result collector; and exit itself
by calling pthread_exit(NULL).
Phenomenon :
A. It takes too long time to wake up the result collector. I checked
the time just before invoking pthread_cond_signal() and right after
returning from pthread_cond_timedwait(). Sometimes, the gap is almost
the same as timeout value in pthread_cond_timedwait().
B. If optimization switch is set as slow one, that is -O0 or -fno-
inline, the waking up delay is no more than 2 milli-seconds. Usually
7~10 micro-seconds.
It puzzled me all this afternoon.
Any answers or hints will be appreciated.
Thank you.
On Mon, 16 Aug 2010, duddn wrote:
> 1. A thread, called result collector, creates a work thread with
> PTHREAD_CREATED_DETACHED attribute by calling pthread_create().
>
> 2. The result collector waits for the worker by calling
> pthread_cond_timedwait() with 1 second timeout value.
>
> 3. The worker does short task(usually under 10 ms) and call
> pthread_cond_signal() to wake up the result collector; and exit itself
> by calling pthread_exit(NULL).
NTPL has a 1:1 mapping from POSIX threads (user-visible concepts) to
kernel schedulable entities. That is, threads are heavy-weight. Creating
and terminating a separate thread for 10ms jobs is hugely wasteful; the
overhead in managing threads will dominate your CPU usage (and wall clock
time).
Batch up jobs. Don't create (heavy-weight) threads just so your
programming task (= expressing what needs to be done) is easier.
Nonetheless, there should be libraries that provide the semblance of
multiple threads (co-routines) without involving KSE's, like GNU Pth [0]
[1].
> Phenomenon :
> A. It takes too long time to wake up the result collector. I checked the
> time just before invoking pthread_cond_signal() and right after
> returning from pthread_cond_timedwait(). Sometimes, the gap is almost
> the same as timeout value in pthread_cond_timedwait().
I think the wall clock time inherent in a signal/timedwait context switch
is not required to be below any specific bound in the general case. (I
suppose this would be different on a hard real-time system.) Said interval
might be as big as the jiffy size [2].
lacos
[0] http://www.gnu.org/software/pth/
[1] http://en.wikipedia.org/wiki/GNU_Portable_Threads
[2] http://www.kernel.org/doc/man-pages/online/pages/man7/time.7.html
> LONG DELAY CASE(C++ app. like below) :
> 1. A thread, called result collector, creates a work thread with
> PTHREAD_CREATED_DETACHED attribute by calling pthread_create().
>
> 2. The result collector waits for the worker by calling
> pthread_cond_timedwait() with 1 second timeout value.
>
> 3. The worker does short task(usually under 10 ms) and call
> pthread_cond_signal() to wake up the result collector; and exit itself
> by calling pthread_exit(NULL).
>
> Phenomenon :
> A. It takes too long time to wake up the result collector. I checked
> the time just before invoking pthread_cond_signal() and right after
> returning from pthread_cond_timedwait(). Sometimes, the gap is almost
> the same as timeout value in pthread_cond_timedwait().
> B. If optimization switch is set as slow one, that is -O0 or -fno-
> inline, the waking up delay is no more than 2 milli-seconds. Usually
> 7~10 micro-seconds.
This is the mistake everybody makes the first time they try to use
condition variables. Consider:
1) Thread A creates thread B.
2) Thread A does quick job.
3) Thread A signals condvar.
4) Thread B gets CPU.
5) Thread B calls pthread_cond_timedwait.
> It puzzled me all this afternoon.
> Any answers or hints will be appreciated.
Despite its name, 'pthread_cond_timedwait' is not a conditional wait.
It's an unconditional wait *for* a condition. You must not call it
unless you have confirmed, under the protection of the mutex it will
release, that there is something to wait for.
The proper way to call pthread_cond_timedwait is as follows:
1) Acquire mutex.
2) Is there something for us to wait for? If not, we're done, STOP.
(Release mutex if appropriate.)
3) Call pthread_cond_timedwait.
4) Did we timeout? If so, we're done, STOP. (Release mutex if
appropriate.)
5) Go to step 2.
DS
Thank you.
> On Aug 16, 6:09 am, duddn <icho...@gmail.com> wrote:
>
>> 1. A thread, called result collector, creates a work thread with
>> PTHREAD_CREATED_DETACHED attribute by calling pthread_create().
>>
>> 2. The result collector waits for the worker by calling
>> pthread_cond_timedwait() with 1 second timeout value.
>>
>> 3. The worker does short task(usually under 10 ms) and call
>> pthread_cond_signal() to wake up the result collector; and exit itself
>> by calling pthread_exit(NULL).
>>
> This is the mistake everybody makes the first time they try to use
> condition variables. Consider:
>
> 1) Thread A creates thread B.
> 2) Thread A does quick job.
> 3) Thread A signals condvar.
> 4) Thread B gets CPU.
> 5) Thread B calls pthread_cond_timedwait.
Shouldn't the letters "A" and "B" be reversed during steps 2-4 of the
explanation? (Here A := result collector, B := worker thread.)
Additionally, my previous post in this thread was stupid. Sorry.
lacos
[...]
>> 1) Thread A creates thread B.
>> 2) Thread A does quick job.
>> 3) Thread A signals condvar.
>> 4) Thread B gets CPU.
>> 5) Thread B calls pthread_cond_timedwait.
>>
>> > It puzzled me all this afternoon.
>> > Any answers or hints will be appreciated.
>>
>> Despite its name, 'pthread_cond_timedwait' is not a conditional wait.
>> It's an unconditional wait *for* a condition. You must not call it
>> unless you have confirmed, under the protection of the mutex it will
>> release, that there is something to wait for.
>>
>> The proper way to call pthread_cond_timedwait is as follows:
>>
>> 1) Acquire mutex.
>> 2) Is there something for us to wait for? If not, we're done, STOP.
>> (Release mutex if appropriate.)
>> 3) Call pthread_cond_timedwait.
>> 4) Did we timeout? If so, we're done, STOP. (Release mutex if
>> appropriate.)
>> 5) Go to step 2.
>
> Thank you.
For a simple scenario like the one described above, using a POSIX
semaphore might be easier.
> Shouldn't the letters "A" and "B" be reversed during steps 2-4 of the
> explanation? (Here A := result collector, B := worker thread.)
Yep. Oddly, it was not because I mistyped them but it was because I
misunderstood his scenario. I thought, and I have no idea why I
thought this, that he was creating a thread and then having the newly-
created thread wait for the creator to finish something before it
began doing work. This is a less-common scenario, and I have no idea
why I thought that was what he was doing.
> Additionally, my previous post in this thread was stupid. Sorry.
You're right about the the importance of not creating threads to do
miniscule amounts of work. I think both of us heard hoofs and thought
of zebras. Just yesterday, not far from where I live, was the one
chance we both had to be right: http://www.kcra.com/news/24650709/detail.html
DS
> I think both of us heard hoofs and thought of zebras. Just yesterday,
> not far from where I live, was the one chance we both had to be right:
> http://www.kcra.com/news/24650709/detail.html
That must have been, like, one wild Saturday night.
Thanks,
lacos
Thank you all.
I've failed to get the root cause but the delay has diminished to
acceptable level.
(High CPU load and frequent context switching might be the cause.)
All in all, thread pool was a good solution.
All your comments were helpful.