Jump to content

Using Threads: Difference between revisions

From EDM2
An initial hello world added
Creating Threads: Added DosCreateThread() example
Line 34: Line 34:


This can be compiled with OpenWatcom like so:
This can be compiled with OpenWatcom like so:
  >wcl386 -cc++ -bm "hello_thread.c++"
  >wcl386 -cc++ -bm "hello_thread.c++"
or with GCC like so:
or with GCC like so:
  >g++ -Zmt "hello_thread.c++"
  >g++ -Zmt "hello_thread.c++"
Here is the same program, using DosCreateThread().
'''NOTE:''' This program deliberately disregards 2 reccommendations:
* It uses std::cout in a thread created by DosCreateThread() as per the notice above.
* It does not end the thread with _endthread() as per the notice below.
From the OS/2 Toolkit 4.5 C Library Reference:
: '''Note:''' If you use DosCreateThread, you must explicitly call _endthread to terminate the thread.
// file: hello_doscreate.c++
#include <iostream>
#include <process.h>
#define INCL_DOSPROCESS
#include <os2.h>
void _System hello( long unsigned int )
{
  std::cout << "Hello from thread." << std::endl;
}
int main( int argc, char *argv[] )
{
  TID tid = 0;
  DosCreateThread( &tid, hello, 0, CREATE_READY | STACK_SPARSE, 4096 * 10 );
  DosSleep( 10 );
}

Revision as of 05:29, 4 November 2007

Rationale

After reading the Pthreads Primer, and attmepting to apply it to eCS, I found a need for an introduction to the API and explanations on how to use it. This is an attempt to fill that void. --Myrkraverk 03:19, 4 November 2007 (CET)

Creating Threads

There are two basic ways to create threads using the OS/2 API, DosCreateThread() and _beginthread(). However, note the following from the OpenWatcom C/C++ Programmers Guide:

WARNING! If any thread calls a library function, you must use the _beginthread function to create the thread. Do not use the DosCreateThread API function.

This makes me want to use _beginthread() all the time, and DosCreateThread() to other people.

There are some differences, between the two calls, which affect how you use them. They are not really interchangable. The most notable differences are the way they return the thread ID to the calling thread, and the parameters passed to the newly created thread are not identical. The former is just a matter of moving parameters around, when changing one call to the other, the other can cause compiler errors and conversion headaces that can propagate throughout the application, which can be quite a nightmare, if a change from one to the other is made at a late stage in development.

Here is a short example:

// file: hello_thread.c++
#include <iostream>
#include <process.h>

#define INCL_DOSPROCESS
#include <os2.h>

void hello( void * )
{
  std::cout << "Hello from thread." << std::endl;
}

int main( int argc, char *argv[] )
{
  _beginthread( hello, 0, 4096, 0 );
  DosSleep( 10 );
}

This can be compiled with OpenWatcom like so:

>wcl386 -cc++ -bm "hello_thread.c++"

or with GCC like so:

>g++ -Zmt "hello_thread.c++"

Here is the same program, using DosCreateThread().

NOTE: This program deliberately disregards 2 reccommendations:

  • It uses std::cout in a thread created by DosCreateThread() as per the notice above.
  • It does not end the thread with _endthread() as per the notice below.

From the OS/2 Toolkit 4.5 C Library Reference:

Note: If you use DosCreateThread, you must explicitly call _endthread to terminate the thread.
// file: hello_doscreate.c++
#include <iostream>
#include <process.h>

#define INCL_DOSPROCESS
#include <os2.h>

void _System hello( long unsigned int )
{
  std::cout << "Hello from thread." << std::endl;
}

int main( int argc, char *argv[] )
{
  TID tid = 0;
  DosCreateThread( &tid, hello, 0, CREATE_READY | STACK_SPARSE, 4096 * 10 );
  DosSleep( 10 );
}