[comp.lang.c] threads for C/C++ under Unix?

hall@eclipse.stanford.edu (Keith Hall) (10/10/89)

  > From: nagle@well.UUCP (John Nagle)
  > What you really need is serious concurrency support.  Here's why.
  >   ...
  > Now how do we get multithread C++?

In his message, John elaborates the utility of lightweight processes.
I agree with him strongly.

As I understand, there is a "task library" that comes with C-Front
which offers coroutines.  What is the state-of-the-art in terms of a
(preferably public domain) portable Unix library that provides
*preemptive* (time-sliced) lightweight processes?  The C-threads
package in Mach would serve as a good model of functionality/interface.

Such a library should provide the usual primitives plus add a layer
atop the standard C-library which protects (thru semaphores) those
functions that require "state", such as malloc, printf, etc.  (The
state must be protected from inconsistent changes by concurrently
executing threads.  The lwp library in SunOS doesn't do this.)  That
layer must also allow threads to run while other threads are blocked
on I/O, etc., which may require that kernel functionality like read &
write be "approximated" with interspersed calls to select.

So, my questions to the net:
  1.  Does a portable preemptive thread package for Unix, such as
      described above, exist?
  2.  Is there a reason such a package cannot be written without
      kernel modifications?
  3.  If kernel mods are required, why haven't we programmer's
      demanded that they be done?  Put another way, is the utility
      of threads not generally recognized?

Thank you for your responses, either to this bboard or back to me.

Keith Hall
hall@eclipse.stanford.edu

peter@ficc.uu.net (Peter da Silva) (10/10/89)

In article <12298@polya.Stanford.EDU> hall@eclipse.stanford.edu (Keith Hall) writes:
>   1.  Does a portable preemptive thread package for Unix, such as
>       described above, exist?

There isn't even a portable non-preemptive threads package. There isn't
even a co-routine package.

>   2.  Is there a reason such a package cannot be written without
>       kernel modifications?

Your quantum would be rather large in most implementations (1 second
for alarm()). Non-preemptive threads could be implemented without any
changes even for systems less powerful than UNIX.

>   3.  If kernel mods are required, why haven't we programmer's
>       demanded that they be done?  Put another way, is the utility
>       of threads not generally recognized?

(a) I don't know. (b) The utility of threads is unrecognised.

I have occasionally tried to drum up some interest in non-preemptive
threads (a whole lot easier to implement -- and safer), with little
success. I wish you luck.
-- 
Peter da Silva, *NIX support guy @ Ferranti International Controls Corporation.
Biz: peter@ficc.uu.net, +1 713 274 5180. Fun: peter@sugar.hackercorp.com. `-_-'
                                                                           'U`
Quote: Structured Programming is a discipline -- not a straitjacket.

libes@cme.nbs.gov (Don Libes) (10/10/89)

In article <6486@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes:
>In article <12298@polya.Stanford.EDU> hall@eclipse.stanford.edu (Keith Hall) writes:
>>   1.  Does a portable preemptive thread package for Unix, such as
>>       described above, exist?
>
>There isn't even a portable non-preemptive threads package. There isn't
>even a co-routine package.

ConcurrenC is preemptive thread package for UNIX based on Xinu.  It is
not entirely portable, but it is as close as possible.

Here is the relevant stuff from a posting by Ken Rodemann in comp.os.xinu:

   ...Unix C library routines are made mutual exclusive, and a
   blocking I/O ConcurrenC task does not block other tasks in the
   system.  The ConcurrenC system includes src for the Xinu/ConcurrenC
   routines, source for modified Unix C library routines, and manual
   pages which list the Xinu name changes within ConcurrenC,
   restricted Unix system calls, etc.

I suggest you read/write the xinu-info@purdue.edu mailing list for
more info.

Don Libes          libes@cme.nist.gov      ...!uunet!cme-durer!libes

prc@erbe.se (Robert Claeson) (10/11/89)

In article <1712@muffin.cme.nbs.gov> libes@cme.nist.gov (Don Libes) writes:

>ConcurrenC is preemptive thread package for UNIX based on Xinu.  It is
>not entirely portable, but it is as close as possible.

And then there's the threads package from Browne University. I don't know
much about the original, but I have some experience using Encore's souped-
up version of it, which they call Encore Parallel Threads.

-- 
          Robert Claeson      E-mail: rclaeson@erbe.se
	  ERBE DATA AB

montnaro@sprite.crd.ge.com (Skip Montanaro) (10/12/89)

In article <12298@polya.Stanford.EDU> hall@eclipse.stanford.edu (Keith Hall)
writes:


   What is the state-of-the-art in terms of a
   (preferably public domain) portable Unix library that provides
   *preemptive* (time-sliced) lightweight processes?  The C-threads
   package in Mach would serve as a good model of functionality/interface.

You can't have preemptive lightweight processes without kernel support. I
know that Stellar's task system is kernel-supported. Ihave no idea how it
compares to the C-threads interface. You can make blocking system calls from
a task, while other tasks in the same process continue execution. This is
not true for task systems that are pure libraries (like Sun's LWP stuff).

--
Skip Montanaro (montanaro@crdgw1.ge.com)

kan@dg-rtp.dg.com (Victor Kan) (10/13/89)

In article <12298@polya.Stanford.EDU> hall@eclipse.stanford.edu (Keith Hall) writes:
>  1.  Does a portable preemptive thread package for Unix, such as
>      described above, exist?

I've know of two systems that might fit the bill.  When I was TAing an
OS course, a grad student working in Columbia's Center for Telecommunications
Research (CTR) wanted to do his concurrent programming assignments using 
some C package that ran on Suns.  I don't know the name of the package, 
but it does exist.  Concurrent C, maybe????  But maybe it's not preemptive.

The other system is Turing Plus (and its ancestor Concurrent Euclid).  
Both come from the University of Toronto's Computer Systems Research
Institute (CSRI).  They are concurrent language systems that can run
under Unix (an unmodified kernel) and both support preemptive, lightweight
threads.  Since both languages are translated into C under Unix, it 
should be possible to link the concurrency simulation kernel (running on
top of the Unix kernel) into other C programs. 

>  2.  Is there a reason such a package cannot be written without
>      kernel modifications?

Nope.

>  3.  If kernel mods are required, why haven't we programmer's
>      demanded that they be done?  Put another way, is the utility
>      of threads not generally recognized?

Threads are recognized by a lot of people.  Unfortunately, most of those
people happen to be in academia and research, rather than commercial
development shops.  It's fine and dandy for researchers at Stanford to
play with lightweight threads in the V system.  But real world 
developers have enough problems debugging multiprocess software systems
that use heavyweight threads (processes).  I know because that's what 
I'm doing now.  Admittedly, many of our local ipc problems wouldn't be 
too bad if we had a single address space to contend with.  Mucking with 
shared memory between processes is a real pain in the butt.

But lightweight threads would make life even tougher.  When I did my
project for a course in parallel architecture and algorithms, I used 
Turing Plus and its lightweight thread features (which I enhanced to 
be parallel).  Conventional debugging, using print statements (with
pseudo-pids for clarification) along with a single thread debugger 
was pretty much useless.  There was simply too much going on at once
to understand what was happening.  Unless somebody develops a real 
concurrent debugger, lightweight threads won't be too useful, outside 
of trivial programs and academic curiosity.

>
>Thank you for your responses, either to this bboard or back to me.
>
>Keith Hall
>hall@eclipse.stanford.edu
>


| Victor Kan               | I speak only for myself.               |  ***
| Data General Corporation | Edito cum Emacs, ergo sum.             | ****
| 62 T.W. Alexander Drive  | Columbia Lions Win, 9 October 1988 for | **** %%%%
| RTP, NC  27709           | a record of 1-44.  Way to go, Lions!   |  *** %%%

djones@megatest.UUCP (Dave Jones) (10/13/89)

From article <MONTNARO.89Oct12124156@sprite.crd.ge.com>, by montnaro@sprite.crd.ge.com (Skip Montanaro):
> 
> You can't have preemptive lightweight processes without kernel support.
>

Hmmm. What kind of kernel support do you need? All that's necessary, I think,
is that it have a "select" routine which can wake up when potentially
blocking system calls would not block. Like Unix does.

You must write a centralized scheduler that knows about I/O, signals,
etc... LWP's would either have to forego standard system calls, or you
would need a lookalike library that substitutes scheduler-based routines
for the blocking calls like getchar(), etc..  But I think it can be done
easily enough under BSD Unix, which has never been advertized as having
kernel support for LWP's.

henry@utzoo.uucp (Henry Spencer) (10/14/89)

In article <8720@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>> You can't have preemptive lightweight processes without kernel support.
>
>Hmmm. What kind of kernel support do you need? All that's necessary, I think,
>is that it have a "select" routine which can wake up when potentially
>blocking system calls would not block. Like Unix does.

You need three pieces of kernel support:  a way to tell when a system call
would block, a way to initiate such an operation without waiting for
completion, and a way to be informed of completion.  "Unix" does *not*
have such things; some *variants* of Unix do... and some don't.
-- 
A bit of tolerance is worth a  |     Henry Spencer at U of Toronto Zoology
megabyte of flaming.           | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

peter@ficc.uu.net (Peter da Silva) (10/14/89)

In article <MONTNARO.89Oct12124156@sprite.crd.ge.com> <montanaro@crdgw1.ge.com> (Skip Montanaro) writes:
> You can't have preemptive lightweight processes without kernel support.

Well, this is a bit of a pleonasm, but all the "kernel support" you need is
alarm(1) and signal(SIGALRM, switch). The quantum is a bit long, but it'll
work. You'll have to rewrite stdio to recover from interrupted system calls,
of course, as well as putting semaphores around the likes of malloc().

The question is whether pre-emptive threads are desirable. Non-preemptive
threads are a lot easier to deal with.
-- 
Peter da Silva, *NIX support guy @ Ferranti International Controls Corporation.
Biz: peter@ficc.uu.net, +1 713 274 5180. Fun: peter@sugar.hackercorp.com. `-_-'
                                                                           'U`
Quote: Structured Programming is a discipline -- not a straitjacket.

darcy@bbm.UUCP (D'Arcy Cain) (10/18/89)

In article <1989Oct13.170846.29846@utzoo.uucp>, henry@utzoo.uucp (Henry
Spencer) writes:
> You need three pieces of kernel support:  a way to tell when a system call
> would block, a way to initiate such an operation without waiting for
> completion, and a way to be informed of completion.  "Unix" does *not*
> have such things; some *variants* of Unix do... and some don't.
When I started reading this subject I thought I knew what a thread was. :-)
Aren't threads just modified forks?  My understanding is that threads
require kernel support because they involve sharing of system resources
specifically the I and D space of the process creating the thread as
opposed to forks which only share I space.  I understood a thread to
cause the following steps to be taken:

A process makes a thread system call similar to a fork call.

The kernel makes an exact duplicate of the calling process' stack space.
It makes no copy of the data space.

A record is kept of the fact that a process now has a new thread.  This
would be similar to the method of keeping track of child processes.

Other than the relation between the calling process and the sharing
of data space, the new thread is set up exactly the same as a process.
It is assigned a CPU time slice, can block on events and otherwise act
like a program.

Both the calling process and the new thread are placed in the ready to
run queue and in turn are eventually are given the CPU. The thread
however can branch to a different set of routines doing a specific
function in the overall program.  Normally this would involve blocking
on an event such as keyboard, mouse or something else.

When a process ends, the I and D space is not returned to the pool
until all threads end themselves or are killed by a signal.

If this roughly sketched activity is what constitutes a thread then 
I can't see how the kernel would not be involved.  If not can someone
please tell me what a thread is.

D'Arcy J.M. Cain
darcy@{cain,bbm}
some sort of linked list since a process may have more than one thread.

djones@megatest.UUCP (Dave Jones) (10/21/89)

From article <802@bbm.UUCP>, by darcy@bbm.UUCP (D'Arcy Cain):
...
> When I started reading this subject I thought I knew what a thread was. :-)
> Aren't threads just modified forks?  My understanding is that threads
> require kernel support because they involve sharing of system resources
> specifically the I and D space of the process creating the thread as
> opposed to forks which only share I space.

  [ Description of his concept of "threads" omited. ... ]

> ... can someone please tell me what a thread is.
> 

What we've been talking about is pretty much what you described, except
that we are not requiring that each thread get its own kernel-directed
scheduling. We are discussing the possibilty of one kernel-scheduled
task implementing several threads, scheduling them "by hand" as is appropriate.
That has advantages and disadvantages. It can make it easier for the threads
to share data-space, and under Unix at least, it will probably be lots
faster than doing one thread per task, (using shared data-segments, and
pipes, one would assume).