Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Concurrency (threads) in C?

0 views
Skip to first unread message

Gerardo

unread,
Mar 6, 2002, 10:57:13 AM3/6/02
to
Hi all,

Is it possible to use threads or similar in C anyhow? Is it needed a
specific library?

Thanks in advance,
Gerardo

Lew Pitcher

unread,
Mar 6, 2002, 11:09:26 AM3/6/02
to
On 6 Mar 2002 07:57:13 -0800, g...@genteole.com (Gerardo) wrote:

>Hi all,
>
>Is it possible to use threads or similar in C anyhow? Is it needed a
>specific library?

No and Yes.

ISO/ANSI C does not make any provision for 'threads' or 'threading' (as in
multithreading a program). However, it isn't too difficult to hand-craft a
co-operative multithreading facility in ISO/ANSI C, so long as you accept some
restrictions on the implementation of the threaded code.

OTOH, there are various _extensions_ to ISO/ANSI C that provide threading
support. These extensions usually take the form of additional libraries (and
associated headers), and are platform (and compiler) dependant.

If you don't want to hand-craft a co-operative multithreading facility in
ISO/ANSI C, you best ask your question in a newsgroup that takes either your OS
or your compiler as it's subject matter.


Lew Pitcher
IT Consultant, Development Services
Toronto Dominion Bank Financial Group

(Opinions expressed are my own, not my employers')

Dann Corbit

unread,
Mar 6, 2002, 11:22:13 AM3/6/02
to
"Gerardo" <g...@genteole.com> wrote in message
news:10d633f3.02030...@posting.google.com...

> Hi all,
>
> Is it possible to use threads or similar in C anyhow? Is it needed a
> specific library?


Yes and no.

No, because the C language itself offers no support for threading.

Yes, because almost every compiler will offer some sort of threading API as
a language extension.

No, because the vendors choose different API's and therefore, you must
resort to nonportable constructs which are (technically speaking) outside of
the C language.

Anyway, just go here:
http://www.imatix.com/html/smt/
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Analysis%20Project%20FAQ.htm


Eric Gorr

unread,
Mar 6, 2002, 1:40:15 PM3/6/02
to
Gerardo <g...@genteole.com> wrote:

> Is it possible to use threads or similar in C anyhow? Is it needed a
> specific library?

Yes. However, such things are specific to your platform.

--
== Eric Gorr ===== http://home.cox.rr.com/ericgorr ===== ICQ:9293199 ===
"Therefore the considerations of the intelligent always include both
benefit and harm." - Sun Tzu
== Insults, like violence, are the last refuge of the incompetent... ===

Maxwelton

unread,
Mar 6, 2002, 3:09:00 PM3/6/02
to
g...@genteole.com (Gerardo) wrote in message news:<10d633f3.02030...@posting.google.com>...

> Hi all,
>
> Is it possible to use threads or similar in C anyhow?

Yes.


>Is it needed a
> specific library?

Yes, you need lpthread.

Maxwelton

Joona I Palaste

unread,
Mar 6, 2002, 3:30:46 PM3/6/02
to
Maxwelton <maxw...@my-deja.com> scribbled the following:

> Yes, you need lpthread.

For POSIX-compatible systems. Amazingly, not every system in the world
is POSIX-compatible.

--
/-- Joona Palaste (pal...@cc.helsinki.fi) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"It's not survival of the fattest, it's survival of the fittest."
- Ludvig von Drake

goose

unread,
Mar 7, 2002, 4:05:49 AM3/7/02
to
Lew Pitcher <Lew.P...@td.com> sucked its thumb and said:
> On 6 Mar 2002 07:57:13 -0800, g...@genteole.com (Gerardo) wrote:
>
>>Hi all,
>>
>>Is it possible to use threads or similar in C anyhow? Is it needed a
>>specific library?
>
> No and Yes.
>
> ISO/ANSI C does not make any provision for 'threads' or 'threading' (as in
> multithreading a program). However, it isn't too difficult to hand-craft a
> co-operative multithreading facility in ISO/ANSI C, so long as you accept some
> restrictions on the implementation of the threaded code.
>

forgive me for being a clueless newbie, but how will i craft a threading
lib just out of ISO/ANSI C ?

some pseudocode might help my understanding here

tia

--
goose

CBFalconer

unread,
Mar 7, 2002, 9:13:07 AM3/7/02
to
goose wrote:
>
... snip ...

>
> forgive me for being a clueless newbie, but how will i craft a
> threading lib just out of ISO/ANSI C ?
>
> some pseudocode might help my understanding here

for (;;) {
process1();
process2();
....
processn();
}

where each process runs for a short time, saves its state, and
returns. Each one might look something like:

if (worktodo) {
dosomeofit();
recordwhereweare();
}

--
Chuck F (cbfal...@yahoo.com) (cbfal...@XXXXworldnet.att.net)
Available for consulting/temporary embedded and systems.
(Remove "XXXX" from reply address. yahoo works unmodified)
mailto:u...@ftc.gov (for spambots to harvest)

Lew Pitcher

unread,
Mar 7, 2002, 12:38:26 PM3/7/02
to
On Thu, 07 Mar 2002 14:13:07 GMT, CBFalconer <cbfal...@yahoo.com> wrote:

>goose wrote:
>>
>... snip ...
>>
>> forgive me for being a clueless newbie, but how will i craft a
>> threading lib just out of ISO/ANSI C ?
>>
>> some pseudocode might help my understanding here
>
> for (;;) {
> process1();
> process2();
> ....
> processn();
> }
>
>where each process runs for a short time, saves its state, and
>returns. Each one might look something like:
>
> if (worktodo) {
> dosomeofit();
> recordwhereweare();
> }

Thank you, Chuck

I meant to reply to this with some example code, but it's on my other
computer, and I won't be able to post until tonight.

Your quick example is alot more suscinct than my example code would have
been, and (although I will post the code) should satisfy the OP's query.

Thanks again.

Lew Pitcher, Information Technology Consultant, Toronto Dominion Bank Financial Group
(Lew_P...@td.com)

(Opinions expressed are my own, not my employer's.)

Lew Pitcher

unread,
Mar 7, 2002, 8:55:45 PM3/7/02
to
Lew Pitcher wrote:
>
> On 6 Mar 2002 07:57:13 -0800, g...@genteole.com (Gerardo) wrote:
>
> >Hi all,
> >
> >Is it possible to use threads or similar in C anyhow? Is it needed a
> >specific library?
>
> No and Yes.
>
> ISO/ANSI C does not make any provision for 'threads' or 'threading' (as in
> multithreading a program). However, it isn't too difficult to hand-craft a
> co-operative multithreading facility in ISO/ANSI C, so long as you accept some
> restrictions on the implementation of the threaded code.

Here's a demo of a limited form of co-operative multithreading using
finite-state-automata application code. It's not robust, and was meant
only as a demo of how this sort of thing could be written in ISO C.

The multithreading support code features:
- a definition of a queue, suitable for use with
enqueue/dequeue and wait/post primatives
- a thread scheduler/dispatcher function
- a thread heap allocation mechanism, suitable
for use in thread state management and storage
- a thread identifier function, suitable for use
in debugging

Although this code has been tested, I make no guarantees as to it's
suitablilty or robustness; it is sample code only.


#include <stdio.h>
#include <stdlib.h>

/*
** definitions for...
** the prototype of a threaded function (TLtask)
** the layout of a thread management data block (TLframe)
** and a macro used to initialize it (TLFrame)
** the layout of a queue (TLqueue)
** and the macro used to initialize it (TLQueue)
*/

typedef int TLtask(int);

struct TLframe
{
struct TLframe *TLF_next; /* next task in queue */

int TLF_tid; /* this task's ID */
TLtask *TLF_task; /* this task's code */
int TLF_state; /* this task's state */
void *TLF_heap; /* this task's data */
};

#define TLFrame(name) struct TLframe name = { NULL, 0, NULL, 0, NULL }


struct TLqueue
{
unsigned long TLQ_count; /* mutex/semaphore */
struct TLframe *TLQ_next; /* first task in queue */
struct TLframe *TLQ_last; /* last task in queue */
};

#define TLQueue(name) struct TLqueue name = { 0,NULL,NULL }

/*
** tl_readyq is the global "ready" queue for our dispatcher
*/
static TLQueue(tl_readyq);

/*
** tl_rdyq() adds a thread to the ready queue
*/
static void tl_rdyq(struct TLframe *newTask)
{
newTask->TLF_next = NULL;

if (tl_readyq.TLQ_last != NULL)
tl_readyq.TLQ_last->TLF_next = newTask;
tl_readyq.TLQ_last = newTask;
if (tl_readyq.TLQ_next == NULL)
tl_readyq.TLQ_next = tl_readyq.TLQ_last;
}

/*
** TL_Task() defines a new thread, and adds it to the ready queue
*/
void TL_Task(TLtask *code)
{
static int threadcount = 0;
struct TLframe *newTask;

if ((newTask = malloc(sizeof *newTask)) != NULL)
{
newTask->TLF_next = NULL;
newTask->TLF_tid = threadcount++;
newTask->TLF_task = code;
newTask->TLF_state = 0;
newTask->TLF_heap = NULL;
tl_rdyq(newTask);
}
}

/*
** TL_GetTLS() returns the address of the thread's private heap
*/
void *TL_GetTLS(void)
{
return tl_readyq.TLQ_next->TLF_heap;
}

/*
** TL_SetTLS() sets the address of the thread's private heap
*/
void *TL_SetTLS(void *heap)
{
return (tl_readyq.TLQ_next->TLF_heap = heap);
}

/*
** TL_GetTID() returns the thread's ID (for thread identification)
*/
int TL_GetTID(void)
{
return tl_readyq.TLQ_next->TLF_tid;
}

/*
** TL_Dispatch() iteratively runs the first thread in the ready
** queue and moves it to the end of the queue when
** it voluntarily suspends it's processing
*/
void TL_Dispatch(int verbose)
{
if (verbose > 0)
printf("TL_Dispatch: Processing begins\n");

while (tl_readyq.TLQ_next != NULL)
{
if (verbose > 1)
printf("\nTL_Dispatch: Switching to task %d\n",
tl_readyq.TLQ_next->TLF_tid);

tl_readyq.TLQ_next->TLF_state =
tl_readyq.TLQ_next->TLF_task(tl_readyq.TLQ_next->TLF_state);

if (verbose > 1)
printf("TL_Dispatch: Task %d is in state %d\n",
tl_readyq.TLQ_next->TLF_tid,
tl_readyq.TLQ_next->TLF_state);

/* ready tasks go to the back of the queue */
/* while complete tasks get discarded */
{
struct TLframe *temp;

temp = tl_readyq.TLQ_next;
tl_readyq.TLQ_next = tl_readyq.TLQ_next->TLF_next;

if (temp->TLF_state != -1)
tl_rdyq(temp);
else
free(temp);
}
}

if (verbose > 0)
printf("TL_Dispatch: Processing ends\n");
}

/************************************************************************************
* User Application logic for use in threads
(tasks) *
************************************************************************************/

/*
** task2() performs a unique application process
**
** it initializes some variables,
** counts down from 10 to 0,
** counts up from 0 to 10,
** cleans up its variables, and
** terminates
*/
int task2(int state)
{
int *p_count;
int tid;

tid = TL_GetTID();

switch (state)
{
case 0:
if (TL_GetTLS() == NULL)
TL_SetTLS(malloc(sizeof(int)));
p_count = TL_GetTLS();
*p_count = 10;

printf("task2 (tid %d): Initialization is Complete\n", tid);
state = 1;
break;

case 2:
p_count = TL_GetTLS();
*p_count = *p_count + 1;
if (*p_count < 10)
state = 2;
else
{
printf("task2 (tid %d): Upcount is Complete\n",tid);
state = 3;
}
break;

case 1:
p_count = TL_GetTLS();
*p_count = *p_count - 1;
if (*p_count > 0)
state = 1;
else
{
printf("task2 (tid %d): Downcount is Complete\n",tid);
state = 2;
}
break;

case 3:
free(TL_GetTLS());
TL_SetTLS(NULL);
printf("task2 (tid %d): Cleanup is Complete\n",tid);
state = -1;
break;

default:
state = -1;
break;
}
return state;
}

/*
** task1() performs another unique application process
**
** it initializes some variables,
** counts up from 0 to 10,
** counts down from 10 to 0,
** cleans up its variables, and
** terminates
*/
int task1(int state)
{
int *p_count;
int tid;

tid = TL_GetTID();

switch (state)
{
case 0:
if (TL_GetTLS() == NULL)
TL_SetTLS(malloc(sizeof(int)));
p_count = TL_GetTLS();
*p_count = 0;
printf("task1 (tid %d): Initialization is Complete\n", tid);
state = 1;
break;

case 1:
p_count = TL_GetTLS();
*p_count = *p_count + 1;
if (*p_count < 10)
state = 1;
else
{
printf("task1 (tid %d): Upcount is Complete\n",tid);
state = 2;
}
break;

case 2:
p_count = TL_GetTLS();
*p_count = *p_count - 1;
if (*p_count > 0)
state = 2;
else
{
printf("task1 (tid %d): Downcount is Complete\n",tid);
state = 3;
}
break;

case 3:
free(TL_GetTLS());
TL_SetTLS(NULL);
printf("task1 (tid %d): Cleanup is Complete\n",tid);
state = -1;
break;

default:
state = -1;
break;
}
return state;
}

/*
** task0() performs an application process as a thread
**
** it launches four threads:
** two threads that perform the task1() processing, and
** two threads that perform the task2() processing
*/
int task0(int state)
{
TL_Task(task1);
TL_Task(task2);
TL_Task(task1);
TL_Task(task2);

return -1;
}

/********************************************************************************/

/*
** main() launches the task0 task, which launches four subtasks
*/
int main(int argc, char *argv[])
{
int verbose = 0;

while (--argc)
if (strcmp(*++argv,"-v") == 0) ++verbose;

TL_Task(task0); TL_Dispatch(verbose);

return EXIT_SUCCESS;
}
/********************************************************************************/

--
Lew Pitcher

Master Codewright and JOAT-in-training
Registered (Slackware) Linux User #112576 (http://counter.li.org/)

goose

unread,
Mar 8, 2002, 5:40:03 AM3/8/02
to
CBFalconer <cbfal...@yahoo.com> sucked its thumb and said:
> goose wrote:
>>
> ... snip ...
>>
>> forgive me for being a clueless newbie, but how will i craft a
>> threading lib just out of ISO/ANSI C ?
>>
>> some pseudocode might help my understanding here
>
> for (;;) {
> process1();
> process2();
> ....
> processn();
> }
>
> where each process runs for a short time, saves its state, and
> returns. Each one might look something like:
>
> if (worktodo) {
> dosomeofit();
> recordwhereweare();
> }
>

thx .. that was very helpfull, but would it not be possible to 'pre-empt'
a thread ?

maybe with a signal you could do something like (pseudocode where
thread_t is typedef to some function pointer type)

thread_t all_threads[num_threads];

thread_t *get_next_thread () {
/*
* decide which thread to run next, return NULL if
* no more threads to run
*/
}

void signal_handler (int sig) {
if (sig==CONTEXT_SWITCH) {
active_thread = get_next_thread ();
}
}

int main () {
...
while (active_thread!=NULL) {
active_thread ();
}
...
return 0;
}

would that be an acceptable way of stopping other threads ? of course,
every single thread MUST be able to complete its current statement, or
function ... maybe another typedef for an 'atom', so that (eg) and assignment
statement is completed before the next thread runs ?


--
goose

CBFalconer

unread,
Mar 8, 2002, 6:07:49 AM3/8/02
to
Lew Pitcher wrote:
>
> Lew Pitcher wrote:
> >
> > On 6 Mar 2002 07:57:13 -0800, g...@genteole.com (Gerardo) wrote:
> >
> > >Is it possible to use threads or similar in C anyhow? Is it
> > >needed a specific library?
> >
> > No and Yes.
> >
> > ISO/ANSI C does not make any provision for 'threads' or
> > 'threading' (as in multithreading a program). However, it isn't
> > too difficult to hand-craft a co-operative multithreading
> > facility in ISO/ANSI C, so long as you accept some restrictions
> > on the implementation of the threaded code.
>
> Here's a demo of a limited form of co-operative multithreading
> using finite-state-automata application code. It's not robust,
> and was meant only as a demo of how this sort of thing could be
> written in ISO C.
>
... snip ...

I see what you meant by 'more succint'. :-)

0 new messages