[H-GEN] pthreads

Byron Ellacott bellacott at hotmail.com
Thu Aug 26 17:04:18 EDT 1999


[ Humbug *General* list - semi-serious discussions about Humbug and
Unix-related topics. ]

>   Pardon me, as I am a newcomer around here, but you should *never* use
>variables for signalling that structures are safe to access.  You simply
>cannot be sure that the access to the variable is atomic, especially in
>this day and age of programming in high level platform-neutral
>languages.  Who knows what code is generated to read or write a variable
>on an X86, PPC or 68k CPU?  The problems are worse if you use a
>multi-CPU machine, where even a single assembly instruction is not
>guaranteed to be atomic.

[0]

note in this case, your argument is correct in a sense, but incorrect in 
another.

The situation (as I read it) would be:

signal_handler() {
	flag_signal = 1;
}

some_loop() {
	while (flag_signal == 0) {
		sleep(some_time);
	}
	/* do action appropriately here */
}

or something similar.  In this context, unless multiple threads are calling 
some_loop(), this code is entirely safe.  Should a strange system somehow 
manage to do the flag_signal = 1 in a non-atomic way, (flag_signal == 0) 
will still only fail once, and once only, even if it occurs in a non-atomic 
way.

If, however, multiple threads are calling some_loop, then it is certainly 
true that race conditions will have occurred.

You will probably find that doing operations on a semaphore, condition 
variable, or whatever will still at some stage do an operation on a mutex, 
and so also will not be safe to call in a signal handler.  My suggestion for 
this case is to have some_loop being a task that runs constantly, with the 
/* appropriate action */ being

	wake_condition_variable(or_whatever_it_is);
	flag_signal = 0;
	/* and reenter while() loop */

You can then have multiple threads wait on that condition variable, and the 
expected behaviour will happen.  Note, however, that this introduces a busy 
loop that is quite probably unnecessary, in that signals are a poor-mans 
threading, usually used to avoid blocking on an exec()/wait() or to set an 
alarm, and so on.  In a threaded world[1], one would create a thread that 
blocks on the result, and avoid the ugly signal issue.

If your signal is to trap a sigsegv or other illegal instruction type 
signal, you probably can't rely on the state of any of your threads anyway, 
and so telling them something is pointless -- handle your failure as 
gracefully as you can and get out before it blows, man.

If your signal is something like sigint, it would be sufficient to set a 
global variable to a value, as per the explanation above, and because it is 
both unlikely you would have multiple threads awaiting a ^C (and if you do, 
you can use one of them to signal the others anyway).

Conclusions:
1) It is safe in a variety of situations to use global variables for 
inter-thread communication.
2) It is (almost) certainly unsafe to use any of the threading library 
communication functions from a signal handler, as they will all eventually 
call a mutex function.
3) You can probably avoid the use of signals altogether.
4) Andrae's tutorial is very good, yes, but covers the use of the library 
more than the concepts of parallel computing, which is what I have attempted 
to cover for this situation.

--
bje

[0] This is directed partly at the original author, and partly at the      
response quoted above.
[1] Living in a material world, and I am a threaded guy?


______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com

--
This is list (humbug) general handled by majordomo at lists.humbug.org.au .
Postings only from subscribed addresses of lists general or general-post.



More information about the General mailing list