tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pthread_cond_signal() ambiguity



On Sat, Jan 23, 2010 at 11:07:58PM +0100, Jean-Yves Migeon wrote:
>>>>> Or wait forever, as it will race against the
>>>>> pthread_cond_signal: thread A acquires the mutex, check
>>>>> condition, but thread B signals a condition change between A
>>>>> wait for it; as B did not acquire the mutex, thread A might not
>>>>> see the signal.
>>>>
>>>> This cannot happen. In order to actually change the condition, B has
>>>> to hold the mutex.  It doesn't matter when B signals the change as long
>>>> as it's not *before* it changes the condition. (But that would be a
>>>> crazy thing to do, so it's not worth thinking about.)
>>>
>>> Never said that B changes the condition. I said that B signals a change.
>>> You have the right to call pth_cd_signal() without enforcing that the
>>> caller modified the condition.
>>
>> Yes, you also have the right to execute *(int *)0xdeadbeef = 172.
>> Both are wrong and will lead to problems.  Your point?
>
> Periodic wakeups, or condvar modification performed in a context  
> different from the one signaling. I do not see how this is wrong or  
> leads to problems. Please elaborate.

If you signal a change when no change happened, then you will get a
spurious wakeup. That's more or less inevitable, in fact it's nearly
definitional. And it's a coding error. You have the "right" to do this
just as you have the "right" to attempt produce SIGSEGV -- your
program may continue correctly or may wander off into the weeds -- but
such "rights" are not very meaningful.

Meanwhile, if you *do* change the condition and signal a wakeup,
there's no guarantee that the sleeper will run before the condition
changes back due to some other activity. This is true regardless of
whether or not you hold the lock when you signal the wakeup. 

As I've noted elsewhere from time to time (possibly earlier in this
thread, in fact) it is perfectly possible to write code that uses
standard synchronization primitives in non-standard ways. Such code
sometimes appears to work, but it's inevitably messy and fragile and
it's never a good idea. Trying to use condition variables without
conditions (e.g. as "gates" of some kind) is a common instance of this
phenomenon. Generally it means you're trying to micro-optimize out a
simple condition; sometimes it means the logic you have in mind would
be expressed better using semaphores.

-- 
David A. Holland
dholland%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index