Cthread man page

CTHREAD(3) Common Library Functions CTHREAD(3)

[1mCthread [22m- [1mLCG Thread [22minferface

[1m#include <Cthread_api.h>[0m

[1mint Cthread_create(void *(*[4m[22mstartroutine[24m[1m)(void *), void * [4m[22marg[24m[1m);[0m

[1mint Cthread_create_detached(void *(*[4m[22mstartroutine[24m[1m)(void *),void *[4m[22marg[24m[1m);[0m

[1mint Cthread_join(int [4m[22mcid[24m[1m, int **[4m[22mstatus[24m[1m);[0m

[1mint Cthread_mutex_lock(void *[4m[22maddr[24m[1m);[0m

[1mint Cthread_mutex_trylock(void *[4m[22maddr[24m[1m);[0m

[1mint Cthread_mutex_timedlock(void *[4m[22maddr[24m[1m, int [4m[22mtimeout[24m[1m);[0m

[1mint Cthread_mutex_unlock(void *[4m[22maddr[24m[1m);[0m

[1mint Cthread_mutex_destroy(void *[4m[22maddr[24m[1m);[0m

[1mint Cthread_cond_wait(void *[4m[22maddr[24m[1m);[0m

[1mint Cthread_cond_timedwait(void *[4m[22maddr[24m[1m, int [4m[22mtimeout[24m[1m);[0m

[1mint Cthread_cond_signal(void *[4m[22maddr[24m[1m);[0m

[1mint Cthread_cond_broadcast(void *[4m[22maddr[24m[1m);[0m

[1mint Cthread_detach(int [4m[22mcid[24m[1m);[0m

[1mint Cthread_kill(int [4m[22mcid[24m[1m, int [4m[22msigno[24m[1m);[0m

[1mint Cthread_exit(void *[4m[22mstatus[24m[1m);[0m

[1mint Cthread_self(void);[0m

[1mint Cthread_getspecific(int *[4m[22mglobal_key[24m[1m, void **[4m[22maddr[24m[1m);[0m

[1mint Cthread_setspecific(int *[4m[22mglobal_key[24m[1m, void * [4m[22maddr[24m[1m);[0m

[1mCthread [22mis a common API interface for multithreaded programs, although
there is also support for nonthreaded application, where some of the
[1mCthread [22mfunctions then becomes useless.

For non-thread applications see the section [1mNON-THREAD ENVIRONMENT[0m

Any created thread is identified uniquely with a [1mcid[22m, standing for
[1mC[22mthread [1mid[22mentifier.

In multithread environment, [1mCthread [22mis an interface to [1mpthread [22mfunc-
tions on [1mUNIX[22m, and an interface to [1mWin32 [22mC-runtime library on [1mWin-[0m

[1mCthread_create [22mis creating a thread given its starting point [4mstartrou-[0m
[4mtine[24m and its arguments [4marg[24m address. The thread is created with the
default parameters, e.g. it is a joinable thread.

Return value is the [1mCthread [22midentifier [4mcid[24m , greater or equal to zero,
or -1 on error.

[1mCthread_create_detached [22mtakes the same arguments as [1mCthread_create [22mand
(tries) to create a detachable thread, which will then make it act as a
daemon. This means that ressources used by this thread will be freed
immediately when it terminates. On the other hand, such thread cannot
be synchronized with other threads using the [1mCthread_join [22mmethod.

You have to remind that creating a detachable thread do not work imme-
diately at the creation step on every thread implementation, in partic-
ular in the [1mDCE [22mthreads. If the implementation do not allow this at
creation time, then [1mCthread_create_detached [22mcalls [1mCthread_create[22m.
Please have a look at [1mCthread_detach [22msection.

Return value is the [1mCthread [22midentifier [4mcid[24m , greater or equal to zero,
or -1 on error.

[1mCthread_exit [22mmakes current thread exiting. If [1mstatus [22misn't NULL, it is
assumed to point to an integer whose value if the status that a
[1mCthread_join [22mwould received, in case the thread is joinable. Please
note that [1mCthread_exit [22mis dangerous and non-recommended on Windows

Return value is 0 on success, or -1 on error.

[1mCthread_kill [22msends [1msigno [22msignal number to the thread [1mcid. [22mThis affect
the status that a [1mCthread_join [22mwould received, in case the thread to be
killed is joinable. Please note that [1mCthread_kill [22mis not supported on
DCE threads.

Return value is 0 on success, or -1 on error.

[1mCthread_join [22msuspends the calling thread until the one identified with
the [1mCthread [22midentifier [4mcid[24m terminates. If the [4mstatus[24m parameter is not
[1mNULL[22m, the status of the terminating thread [4mcid[24m is stored there. This
status is the pointer returned by thread [4mcid[24m at its end.

Return value is 0 on success, or -1 on error.

[1mCthread_mutex_lock [22mis an alias for [1mCthread_mutex_timedlock [22mwith a [4mtime-[0m
[4mout[24m of -1.

[1mCthread_mutex_trylock [22mis an alias for [1mCthread_mutex_timedlock [22mwith a
[4mtimeout[24m of 0.

[1mCthread_mutex_timedlock [22mis acquiring a mutex, creating it if necessary,
on the [4maddr[24m address. The second parameter is the eventual [4mtimeout[24m in
seconds. If this parameter is < 0, the calling thread is suspended
until it is granted access to [4maddr[24m , if it is zero, the calling thread
will try to gain the lock, and if it is greater than zero the calling
thread will wait up to [4mtimeout[24m seconds.

Please note that, in [1mCthread[22m, a creation of a mutex is always associ-
ated with a creation of a conditionnal variable. See
[1mCthread_cond_timedwait [22mand [1mCthread_cond_broadcast_[22m.

Return value is 0 on success, or -1 on error.

[1mCthread_mutex_unlock [22mis unlocking the mutex that the calling thread is
assumed to have acquired previously, calling [1mCthread_mutex_timedlock [22mon
the [4maddr[24m address.

[1mCthread_cond_wait [22mis an alias for [1mCthread_cond_timedwait [22mwith a [4mtimeout[0m
of -1.

[1mCthread_cond_timedwait [22mis waiting for a condition variable, which is,
by default in [1mCthread[22m, broadcasted, associated with a mutex previously
created on the [4maddr[24m address. Calling this function before the creation
[1mand [22mthe lock of a mutex, with [1mCthread_mutex_timedlock [22mis a programming

While the thread is waiting on a condition to arise on the [4maddr[0m
address, the corresponding lock is released. It will be acquired as
soon as the condition happens. Please note that the use of condition is
subject to normal thread programming rules, e.g. the lock, a loop on a
predicate, a wait inside the loop, and the unlock.

If the [4mtimeout[24m parameter, in seconds, is greater than zero, then the
function will not suspend the calling thread more than this limit.

Return value is 0 on success, or -1 on error.

[1mCthread_cond_signal [22mis an alias for [1mCthread_cond_broadcast[22m.

[1mCthread_cond_broadcast [22mrestarts threads that are waiting on a condition
variable vs. [4maddr[24m address.

Return value is 0 on success, or -1 on error.

[1mCthread_detach [22mis detaching the calling thread, identified with [4mcid[0m
[1mCthread [22midentifier. Whereas the normal thread packages that allow a
thread to be detached at the creation step, see [1mCthread_cre-[0m
[1mate_detached[22m, returns an error if such a detached thread tries to
detach himself again, [1mCthread_detach [22mwill not, because of this differ-
ent behaviour vs. different thread implementations: it is not possible
everywhere to create a detached thread immediately, like in DCE

This means that if a user is creating a thread with [1mCthread_create [22mor
[1mCthread_create_detached[22m, the created thread will, in any case, be
allowed to call [1mCthread_detach[22m: if the calling thread is not yet
detached, it will be changed so forth, and if the calling thread is
already detached, the return value will be 0.

Return value is 0 on success, or -1 on error.

[1mCthread_mutex_destroy [22mis removing its corresponding entry in [1mCthread[0m
internal linked list, freeing all thread associated stuff, like the
mutex itself, and the conditionnal variable (see [1mCthread_mutex_timed-[0m

Return value is 0 on success, or -1 on error.

[1mCthread_self [22mis returning the [1mCthread [22midentifier [4mcid[24m of the calling

Return value is the [4mcid[24m (greater or equal to zero) on success, or -1 on

[1mCthread_getspecific [22mis creating and/or getting a thread-specific stor-
age address for every instance of the [4mglobal_key[24m address, storing its
result in [4maddr[24m location. The first time it is called, the stored result
is [1mNULL[22m, next time it will be the address of the memory the user would
have previously allocated and associated with the key using

Return value is 0 on success, or -1 on error.

[1mCthread_setspecific [22mis associating a memory, starting at [4maddr[24m that he
have previously allocated, with the [4mglobal_key[24m address. If he tries to
do so without calling previously [1mCthread_getspecific[22m, then such a call
will be done internally.

Return value is 0 on success, or -1 on error.

Beyond the errno value, [1mCthread [22mis setting the serrno value to generic
values that can be:

LCG Thread interface initialization error

A thread initialisation call failed. In principle, on UNIX this
will be a call to pthread_mutex_init (and possibly
pthread_mutexattr_init) that failed, on Windows/NT this might be
a call to CreateMutex.

LCG Thread interface failure in calling your thread library

A thread call to your native system library (like the pthread
one on UNIX) failed. Please note that this is differentiated to
the Cthread initialization and can happen if you are using too
much thread keys, for example. This is really a run-time error
only concerning your operating system thread interface. Any
other system call failure, but not a thread one, and not at the
initialisation step, will set serrno to [1mSEINTERNAL[0m

Operation not supported

This can be generated only if you compiled Cthread with a
-DCTHREAD_PROTO flag that Cthread do not know about. Check your
LCG configuration site.def.

Internal error

You can have more information by compiling the Cthread package
with the flag -DCTHREAD_DEBUG, and catching the printout on your
stderr stream. This is any system call that failed (like mal-
loc()), except those to the thread library (for which SECTHREAD-
ERR or SECTHREADINIT is to be found), or any critical internal
run-time error (such as a non correct value found in some
Cthread internal structures).

[1mSETIMEDOUT [22m(routines with a timeout parameter only)
Timed out

You called a routine with a timeout value greater than zero that
reached the maximum number of timeout seconds in waiting state.

Invalid parameters

You called a routine with invalid parameter(s). Please check
your code.

[1mHere is an example with thread-specific data[0m

#include <Cthread_api.h> /* [1mCthread [22minclude file */
#include <stdio.h> /* For I/O functions and definitions */
#define NTHREADS 5 /* Number of threads */
#define NLOOP 5 /* Number of loops in threads */

static int global_key;

/* Internal Prototypes */
void *mythread(void *);
void testit();

int main() {
int i, n;

for (i=1; i <= NTHREADS; i++) {
if ((n = [1mCthread_create[22m(&mythread,NULL)) < 0) {
} else {
fprintf(stderr,"[main] --> Created Cthread ID %d0,n);


void *mythread(void *arg) {
int i;

/* Call the same routine NLOOP times */
for (i=1; i <= NLOOP; i++) {


void testit() {
char *addr = NULL;
int n;

if ((n = [1mCthread_detach[22m(Cthread_self())))

if ((n = [1mCthread_getspecific[22m(&global_key,(void **) &addr)))

if (addr == NULL) {
addr = malloc(100);
fprintf(stderr,"[%d] --> new 0x%x0,
if ([1mCthread_setspecific[22m(&global_key,addr))
} else {
fprintf(stderr,"[%d] --> old 0x%x0,

sprintf(addr,"[%d] Print with TSD buffer : Cthread ID=%d0,



In such an environment, almost all methods becomes no-op, except:

Creation of process(es):
[1mCthread_create_detached [22m(equivalent to [1mCthread_create[22m)

Use of "Process"-specific variables:

For these two last functions, [1mCthread [22mwill garbage itself its
eventual list of "Process"-specific variables. This means that,
[1mas in a thread environment[22m, the user will [1mnot [22mhave to free mem-
ory allocated [1mand [22mregistered with a call to [1mCthread_setspecific[22m.

[1mSEE ALSO[0m
[1mpthread[22m, [1mDCE[22m, [1mLinuxThreads[22m, [1mWin32[0m

[1mLCG Grid Deployment [22mTeam

LCG $Date: 2005/03/29 09:27:18 $ CTHREAD(3)