RU/2: Форум. Общение пользователей и разработчиков OS/2 (eCS). : Multithreading (VI)


Список сообщений | Написать новое | Ответить на сообщение | Домой Поиск:
Предыдущее сообщение | Следующее сообщение
From : ???
To : All
Subj : Multithreading (VI)

Example 1. - A thread creation under C/2

This first simple Example 1. shows how to create one new thread in C under OS/2 32-bit which has the number 2, called Thread Identifier (TID) 2. For any C environment there have to considered special conditions like the condition for the stack space. The main program starts with TID 1.

To create the thread here it is used the C library function _beginthread.

Definition of _beginthread:

#include <stdlib.h> /* also defined in <process.h> */

int _beginthread(void (*start_address) (void *),
(void *)stack,
unsigned stack_size,
void *arglist);


Language Level: Extension

The _beginthread function creates a new thread. It takes the following arguments:

start_address:

This parameter is the address of the function that the newly created thread will
execute. When the thread returns from that function, it is terminated
automatically. You can also explicitly terminate the thread by calling _endthread.

stack:

This parameter is ignored, but is retained to ease migration of C/2 programs.
The C/2 compiler requires the second parameter to be the address of the bottom
of the stack that the new thread will use. Because the OS/2 operating system
automatically takes care of stack allocation, the parameter is not needed.

stack_size:

The size of the stack, in bytes, which is to be allocated for the new thread.
The stack size should be a nonzero multiple of 4K and a minimum of 8K(!). Memory
is used when needed, one page at a time.

arglist:

A parameter to be passed to the newly created thread. It is the size of a
pointer, and is usually the address of a data item to be passed to the new
thread, such as a char string. It provides _beginthread with a value to pass to
the child thread. NULL can be used as a placeholder.

The function that the new thread will perform must be declared and compiled
using _Optlink linkage.

An alternative to this function is the OS/2 DosCreateThread API. If you use
DosCreateThread, you must also use a #pragma handler statement for the
thread function to ensure proper C exception handling. You should also call the
_fpreset function at the start of the thread to preset the 387 control status word
properly. The use of DosCreateThread requires the use of _endthread to
terminate the thread.

Note: When using the _beginthread and _endthread functions, you must specify
the /Gm+ compiler option to use the multithread libraries.

If successful, _beginthread returns the thread ID number of the new thread. It
returns -1 to indicate an error.


Example of _beginthread :


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

This example uses _beginthread to start a new thread bonjour,
which prints Bonjour! five times and then implicitly ends itself. The
program then prints a statement indicating the thread identifier number
for bonjour.

Note: To run this example, you must compile it using the /Gm+
compiler option for C/2


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


#define INCL_DOS
#define INCL_DOSERRORS /* DOS error values */
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>

static int wait = 1;

void bonjour(void *arg)
{
int i = 0;

while (wait)
/* wait until the thread id has been printed */
DosSleep(0l);

while ( i++ < 5 )
printf("Bonjour!\n");
}

int main(void)
{
unsigned long tid;

tid = _beginthread(bonjour, NULL, 8192, NULL);

if ( tid == -1 )
{
printf("Unable to start thread.\n");
exit(-1);
}
else
{
printf("Thread started
with thread identifier number %d.\n", tid);
wait = 0;
}

DosWaitThread( &tid, DCWW_WAIT );
/* wait for thread bonjour to end */
/* before ending main thread */

return 0;

/* The expected output
(with possible thread id number) is: */

Thread started with thread identifier number 2.
Bonjour!
Bonjour!
Bonjour!
Bonjour!
Bonjour! */

}


Remarks:

The first action of the program is to print the message in the main program:

"Thread started with thread identifier number ...". Because the thread(i.e. program
execution) runs parallel(!) with the created thread of the routine bonjour, a control
variable "wait" let run the while loop for DosSleep until the message from the main
program is printed.

Then the thread 2 of the routine bonjour can start to print the message loop 5 times.
The execution runs back to the main program. Because the execution of this
printing can last it must be avoided that the return of the main program ends the running
thread 2 of the routine bonjor. Therefore there is the call of DosWaitThread, which
holds the main program until thread 2 (connected via the TID address) ends.

The option DCWW_WAIT in DosWaitThread means:

The current thread waits until a thread ends. If a thread has already ended, the call
returns immediately with the TID.

One can define a return code like this:

rc = DosWaitThread(&tid, DCWW_WIT)

If (rc != NO_ERROR) {

printf ("DosWaitThread error: return code = %\n", rc);

}


The return code of DosWaitThread are:

0 --- NO_ERROR

95 -- ERROR_INTERRUPT

294 - ERROR_THREAD_NOT_TREMINATED

309 - ERROR_INVALID_THREADID


In a later lession the OS/2 API DosWaitThread will defined more detailed.



Sun 28 Dec 2003 17:35 Mozilla/4.61 [en] (OS/2; U)




Programmed by Dmitri Maximovich, Dmitry I. Platonoff, Eugen Kuleshov.
25.09.99 (c) 1999, RU/2. All rights reserved.
Rewritten by Dmitry Ban. All rights ignored.