Boston Linux & Unix (BLU) Home | Calendar | Mail Lists | List Archives | Desktop SIG | Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings
Linux Cafe | Meeting Notes | Blog | Linux Links | Bling | About BLU

BLU Discuss list archive


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

Pthreads & Signals.



On Thursday 18 November 2004 12:39 pm, you wrote:

> The reality is that if somebody raises a signal (an actual Unix
> signal, not the things we have been discussing so far in this thread)
> on the process that is running this code and pthread_cond_wait() is
> interrupted, the program will act unpredictably.  I still contend that
> nearly any call to pthread_cond_wait() that is not enclosed in a
> proper loop is incorrect.
This is true, but:
if (lock == 0) {
	result = pthread_cond_wait(cond, mutex);
	lock = 1;
}
This loop is wrong. A more appropriate loop is:
for(;;) { // wait forever
	result = pthread_cond_wait(cond, mutex);
	if (result ==  EINTR) // wait interrupted by signal
		continue; 
	if (result == 0)
		break;
}
You might set a better predicate, and maybe do different things on a signal 
or a busy. In a non-timed wait, you will not get a timeout. The signal 
handler may set a stop variable, for instance, so instdead of for(;;) you 
might have, while(running). 

The overal point is that in Tony's example, I was pointing out the proper 
use of a mutex and cond_wait. One could very easily accomplish the same 
thing with a mutex, a loop with a sleep in it. The loop would continue 
until the other thread changed the loop predicate. A very simple, and not 
100% correct might be:

parent thread:
	lock mutex
	lock = 1;
	unlock mutex
	
	create_child
	while(lock == 1)
		sleep
	lock = 1; // allow child to run
	join
	return

child thread:
	sleep // let parent loop a bit
	lock mutex
	lock = 0;
	unlock mutex
	while(lock == 0)
		sleep
	return


This accomplishes the same thing. Note that I intentionally did not place a 
mutex around the reading of lock. While the reading of lock may not be 
atomic, in this case, I don't care. In a more complex example where I have 
a data structure or multiple variables, then I would surround the read with 
a mutex:
	for(;;) {
		lock mutex
		if (lock == 0) {
			unlock mutex
			sleep
		} else {
			unlock mutex
			break
		}
	}
This does the same thing as while(lock == 0) except that it makes the test 
atomic. 
-- 
Jerry Feldman <gerald.feldman at hp.com>
Partner Technology Access Center (contractor) (PTAC-MA)
Hewlett-Packard Co.
550 King Street LKG2a-X2
Littleton, Ma. 01460
(978)506-5243




BLU is a member of BostonUserGroups
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org