LinuxThreads are Light Wieght Processes, (actually, Linus calls them
COEs, Contexts Of Exectution,
to distinguish them from sSn LWPs, which apparently arent as slick).
For Some Reason though,...
The threads (processes) in a task use SIGUSR1, SIGUSR2 to 'communicate'.
Does anyone know why sysV IPC (semaphores, shared-memory, queues) wasnt
used ?
To this uninformed observer, any of them seem to afford a richer
protocol in which to pass
info between threads.
SysV IPC is there; semget, shmget, msgget are all implemented.
Portability ? Presumably a non-issue because sysV is in Linux
No need for fancy Communications ? what exactly is signalled, and when,
and why 2 signals ?
Speed? Signals are historically un-reliable, I kinda thought this
meant that they were slow too.
And why does dedicating a separate thread for signal handling make
signals reliable ?
Here's the reason why or atleast according to the author :
This is from LinuxThreads FAQ (url :
http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html)
<<<<<< End of quote >>>>>>
H.4: With LinuxThreads, I can no longer use the signals SIGUSR1 and SIGUSR2
in my programs! Why?
LinuxThreads needs two signals for its internal operation. One is used to
suspend and restart threads blocked on
mutex, condition or semaphore operations. The other is used for thread
cancellation. Since the only two signals not
reserved for the Linux kernel are SIGUSR1 and SIGUSR2, LinuxThreads has no
other choice than using them. I know
this is unfortunate, and hope this problem will be addressed in future
Linux kernels, either by freeing some of the
regular signals (unlikely), or by providing more than 32 signals (as per
the POSIX 1003.1b realtime extensions).
In the meantime, you can try to use kernel-reserved signals either in your
program or in LinuxThreads. For instance,
SIGSTKFLT and SIGUNUSED appear to be unused in the current Linux kernels
for the Intel x86 architecture. To use
these in LinuxThreads, the only file you need to change is internals.h,
more specifically the two lines:
#define PTHREAD_SIG_RESTART SIGUSR1
#define PTHREAD_SIG_CANCEL SIGUSR2
Replace them by e.g.
#define PTHREAD_SIG_RESTART SIGSTKFLT
#define PTHREAD_SIG_CANCEL SIGUNUSED
Warning: you're doing this at your own risks.
<<<<<< End of quote >>>>>>
Hope this helps,
wilson
Most people just call the kernel threads, because they are threads
that the kernel is aware of (as opposed to user-mode threads).
LWP is what kernel threads are called in SunOS, more or less.
> For Some Reason though,...
>
> The threads (processes) in a task use SIGUSR1, SIGUSR2 to 'communicate'.
>
> Does anyone know why sysV IPC (semaphores, shared-memory, queues) wasnt
> used ?
>
> To this uninformed observer, any of them seem to afford a richer
> protocol in which to pass
> info between threads.
>
> SysV IPC is there; semget, shmget, msgget are all implemented.
Richness isn't needed. Since the threads share all memory, any kind of
data structure (queues etc.) can just be built in memory, as rich as
you like.
What is needed is:
1) A way to wake a blocked thread (e.g. blocked on a mutex, condition
variable, or in pthread_join).
2) A way to implement asynchronous thread cancellation: There has to
be a way to make a thread call pthread_exit(), no matter it is doing
at the time.
The SysV IPC mechanisms could be used for (1), but not (2) because
they are entirely synchronous. Furthermore, they take up kernel
resources, whereas signals normally don't.
> Portability ? Presumably a non-issue because sysV is in Linux
>
> No need for fancy Communications ? what exactly is signalled, and when,
> and why 2 signals ?
(1) and (2) above. It would be possible to use one signal for both
purposes, but if it ain't broke, don't fix it.
> Speed? Signals are historically un-reliable, I kinda thought this
> meant that they were slow too.
They are neither slow. Since they don't carry any data, they are in
principle the fastest IPC mechanism in Unix (and for Linux, this holds
in practice too).
Historically they have been seen as hard to program with, because
there are strict conditions on what it is safe to do in a signal
handler, and because there are pitfalls when using any kind of
asynchronous facility. As a result, people would write naïve code that
worked some of the time, but failed occasionally. I suppose this gave
the false impression that signals are unreliable. There were also
differences in some of the details of signals between Unices, so they
were an obstacle to portability in the bad old pre-POSIX days.
> And why does dedicating a separate thread for signal handling make
> signals reliable ?
LinuxThreads doesn't dedicate a thread to signal handling. It
dedicates a thread to managing the creation and termination of
threads. One thread has to be the parent of all the other threads, so
that it can detect when any of them are killed.
Dave Wragg
thx for those direct answers. I had some suspicions as to the reasons,
but all your answers seem consistent with each other and with what
I thought I knew.
Jim Cromie
> principle the fastest IPC mechanism in Unix (and for Linux, this holds
> in practice too).
makes sense, simpler (and less data) means faster.
> > And why does dedicating a separate thread for signal handling make
> > signals reliable ?
BTW, any specific actions that are bad to try in a signal handler ?
Its sometimes arbitrarily hard to avoid nieve actions.
> LinuxThreads doesn't dedicate a thread to signal handling. It
> dedicates a thread to managing the creation and termination of
> threads. One thread has to be the parent of all the other threads, so
> that it can detect when any of them are killed.
Linux itself may not, but I gather that it is a typical strategy to deddicate
a
thread to signal handling, (or perhaps better stated as, ignoring signals in
all threads but one), causes the signals to be caught by the signal-handler
thread (maybe the same one that manages the other threads).
It seems reasonable that a thread handling the signals provides better
protection from potentially disruptive handler actions. This approach
relys on the relative independence of the threads.
I also recall (with a little uncertainty) that POSIX dictates that signals
cannot
be forced to a given thread, which implies (in a backwards sort of way), that
any thread in a group could equivalently handle a signal. So if other
threads are
ignoring signals, the remaining one must get them and handle them.
This also seems consistent with the traditiional signal handling strategy;
do as little as possible in the handler - set a flag, then let the MainLoop
(tk or otherwize) read the flag and handle the remaining work when it
gets to it (synchronously doesnt quite apply does it). In a threaded
situation, the signal handler thread can do more work safely by itself,
and can synchronize with the others.
No reason the two should have any connection. Solaris is slow, Linux
2.1.44 was unreliable, NT is both. (:
[David Wragg <d...@doc.ic.ac.uk>]
> Historically they have been seen as hard to program with, because
> there are strict conditions on what it is safe to do in a signal
> handler, and because there are pitfalls when using any kind of
> asynchronous facility. As a result, people would write na=EFve code
> that worked some of the time, but failed occasionally. I suppose
> this gave the false impression that signals are unreliable.
You have a good point ... but probably the main reason signals have
been seen as unreliable is because on some older Unices (4.3BSD?) they
really *were* unreliable. Signal handlers were single-use and had to
reinstall themselves, and this meant a race window after a handler got
called and before it called signal() to reinstall itself, and any more
of the same signal would either get dropped or would kill the process,
depending on the particular signal. Come to think of it, even in POSIX
you will drop duplicate signals, since they don't get queued past a
single bitmask, but at least you don't have to die from a SIGINT you
wanted to handle.
--
Peter Samuelson
<sampo.creighton.edu!psamuels>
So start your own thread. (No pun intended.) (Actually it was
intended, and I'm almost sorry.)
> I wrote a simple program in Solaris which allowed me to
> suspend/resume threads from keyboard within a process (kill
> SIGUSR1/SIGUSR2 pid).
> Same program will crash on Linux since pthread (I think) creates a
> process per thread.
Actually same program will do weird things on Linux since until fairly
recently, LinuxThreads (the standard pthreads implementation on Linux)
used SIGUSR1/SIGUSR2 internally. I believe the situation has been
resolved since the kernel now allows more signals than before.
Whether your program will work on Linux assuming it doesn't stomp on
the two pthreads-internal signals, I do not know. But a more accurate
way to put your statement is that Linux creates a thread for every
process, not a process for every thread. So each thread has a unique
PID (or TID, if you will) just like each process does. I haven't tried
it but you should be able to put a thread to sleep by sending it a
SIGSTOP, just like you can a single-threaded process. [If a Real
Threads Programmer reads this and frowns, please correct and ridicule
me to your heart's content....]
> My question is, what version of pthreads is likely to have decent
> implementation of threads which will allow me to suspend/resume
> threads arbitrarily ?(more like NT, basically I want to implement
> ResumeThread/ SuspendThread calls) and not created stupid processes ?
Hmmm, don't know if there are other threads implementations, but if I
remember correctly you might at least upgrade to a recent glibc (if you
haven't already) so it won't stomp on your SIGUSR1/USR2. (At least
there was talk of using different signals ... I don't actually know
that it took place.)
As to stupid processes, the processes will only be as stupid as the
code you wrote for them.... (:
--
Peter Samuelson
<sampo.creighton.edu!psamuels>
I wrote a simple program in Solaris which
allowed me to suspend/resume threads from
keyboard within a process (kill SIGUSR1/SIGUSR2
pid).
Same program will crash on Linux since pthread (I
think) creates a process per thread.
My question is, what version of pthreads is likely
to have decent implementation of threads which will
allow me to suspend/resume threads arbitrarily ?(more
like NT, basically I want to implement ResumeThread/
SuspendThread calls) and not created stupid processes ?
Thanks,
Rakesh.