Jump to content

Using Threads: Difference between revisions

From EDM2
No edit summary
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
: '''NOTICE: This is currently Work In Progress.'''
== Rationale ==
== Rationale ==
 
After reading the Pthreads Primer, and attempting 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.  --[[User:Myrkraverk|Myrkraverk]] 03:19, 4 November 2007 (CET)
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.  --[[User:Myrkraverk|Myrkraverk]] 03:19, 4 November 2007 (CET)


== Use of C++ in the Examples ==
== Use of C++ in the Examples ==
I am a C++ programmer and frequently run into "small differences" when attempting to use a plain C compiler. These are mostly differences in automatic variable declaration and initialization which are leveraged somewhat with C99. However, I do not want to spend my time battling "plain C" syntax peculiarities or C99 feature command line switches, so I simply compile all my examples as C++.


I am a C++ programmer and frequently run into "small differences" when attempting to use a plain C compiler.  These are mostly differences in automatic variable declaration and initialization which are leveraged somewhat with C99.  However, I do not want to spend my time battling "plain C" syntax peculiarites or C99 feature command line switches, so I simply compile all my examples as C++.
The only "especially C++" feature I use is std::cout instead of printf() which any reasonably proficient C programmer can translate on the spot.
 
The only "especially C++" feature I use is std::cout instead of printf() which any resonably proficient C programmer can translate on the spot.


== Creating Threads ==
== Creating Threads ==
Thread creation can be done with the [[DosCreateThread]]() system call, or the C runtime library [[_beginthread]]() function.


Thread creation can be done with the [[OS2 API:DosCreateThread | DosCreateThread()]] system call, or the C runtime library [[OS2 API:CLR:_beginthread | _beginthread()]] function.
The DosCreateThread() system call is inherently low level and does not initialize the C/C++ runtime environment. In particular:
 
* You can not assume C++ Exceptions will work. VisualAge C++ has #pragma handler for this but it '''can not be relied upon''' with OpenWatcom or GCC.
The [[OS2 API:DosCreateThread | DosCreateThread()]] system call is inherently low level and does not initialize the C/C++ runtime environment. In particular:
* You can not rely on the state of the floating point unit. You can however, reset it with <tt>_fpreset()</tt>.
 
* You can not rely on [[DosExit]]() to clear up thread specific data and/or the runtime environment; use <tt>_endthread()</tt> instead.
* You can not assume C++ Exceptions will work. VisualAge C++ has #pragma handler for this but it '''can not be relied upon''' with OpenWatcom or GCC.
: That is, the C/C++ runtime environment may be initialized on first use (this is documented for VisualAge C++ but apparently not for OpenWatcom or GCC). Also:
 
* You can not rely on the state of the floating point unit. You can however, reset it with [[OS2 API:CLR:_fpreset | _fpreset()]].
 
* You can not rely on [[OS2 API:DosExit | DosExit()]] to clear up thread specific data and/or the runtime environment; use [[OS2 API:CLR:_endthread | _endthread()]] instead.
 
: That is, the C/C++ runtime environment may be initialized on first use (this is documented for VisualAge C++ but aparently not for OpenWatcom or GCC). Also:
 
:: From the OpenWatcom C/C++ Programmer's Guide:
:: From the OpenWatcom C/C++ Programmer's 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.
::: '''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.


:: From the OS/2 Toolkit 4.5:
:: From the OS/2 Toolkit 4.5:
::: '''Note:''' If you use DosCreateThread, you must explicitly call _endthread to terminate the thread.
::: '''Note:''' If you use DosCreateThread, you must explicitly call _endthread to terminate the thread.


None of this is an issue when using [[OS2 API:CLR:_beginthread | _beginthread()]]; it takes care of setting up the runtime environment and tearing it down when the thread function ends.
None of this is an issue when using <tt>_beginthread()</tt>; it takes care of setting up the runtime environment and tearing it down when the thread function ends.


==== Hello, Threaded World! ====
==== Hello, Threaded World! ====
 
Here is a short example of <tt>_beginthread()</tt>:
Here is a short example of [[OS2 API:CLR:_beginthread | _beginthread()]]:
 
  // file: hello_thread.c++
  // file: hello_thread.c++
  #include <iostream>
  #include <iostream>
Line 58: Line 44:


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 that it uses a library call, despite the warnings above.
Here is the same program, using DosCreateThread(). Note that it uses a library call, despite the warnings above.


  // file: hello_doscreate.c++
  // file: hello_doscreate.c++
Line 86: Line 68:


== References ==
== References ==
 
* [[UsingThreads:SynchronizationTimings | Synchronization Timings]]
* [[OS2 API | OS/2 API Project]]
* [http://www.openwatcom.org/ftp/manuals/1.5/pguide.pdf OpenWatcom C/C++ Programmer's Guide] (pdf) - Links to version 1.5 of the manual.
* [http://www.openwatcom.org/ftp/manuals/1.5/pguide.pdf OpenWatcom C/C++ Programmer's Guide] (pdf) - Links to version 1.5 of the manual.
* [http://www.openwatcom.org/ftp/manuals/1.5/clib.pdf OpenWatcom C Library Reference] (pdf) - Links to version 1.5 of the manual.
* [http://www.openwatcom.org/ftp/manuals/1.5/clib.pdf OpenWatcom C Library Reference] (pdf) - Links to version 1.5 of the manual.
Line 93: Line 74:
** Control Program Programming Guide and Reference
** Control Program Programming Guide and Reference
** C Library Reference
** C Library Reference
* [http://hobbes.nmsu.edu/pub/os2/dev/emx/v0.9d/emxview.zip EMX 0.9d Documentation] (inf zip) - Direct download link on Hobbes.
* {{FileLink|EMX_0-9d.zip}}. EMX 0.9d Documentation on /book (inf).
 
[[Category:C++ Articles]]

Latest revision as of 17:09, 27 January 2024

Rationale

After reading the Pthreads Primer, and attempting 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)

Use of C++ in the Examples

I am a C++ programmer and frequently run into "small differences" when attempting to use a plain C compiler. These are mostly differences in automatic variable declaration and initialization which are leveraged somewhat with C99. However, I do not want to spend my time battling "plain C" syntax peculiarities or C99 feature command line switches, so I simply compile all my examples as C++.

The only "especially C++" feature I use is std::cout instead of printf() which any reasonably proficient C programmer can translate on the spot.

Creating Threads

Thread creation can be done with the DosCreateThread() system call, or the C runtime library _beginthread() function.

The DosCreateThread() system call is inherently low level and does not initialize the C/C++ runtime environment. In particular:

  • You can not assume C++ Exceptions will work. VisualAge C++ has #pragma handler for this but it can not be relied upon with OpenWatcom or GCC.
  • You can not rely on the state of the floating point unit. You can however, reset it with _fpreset().
  • You can not rely on DosExit() to clear up thread specific data and/or the runtime environment; use _endthread() instead.
That is, the C/C++ runtime environment may be initialized on first use (this is documented for VisualAge C++ but apparently not for OpenWatcom or GCC). Also:
From the OpenWatcom C/C++ Programmer's 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.
From the OS/2 Toolkit 4.5:
Note: If you use DosCreateThread, you must explicitly call _endthread to terminate the thread.

None of this is an issue when using _beginthread(); it takes care of setting up the runtime environment and tearing it down when the thread function ends.

Hello, Threaded World!

Here is a short example of _beginthread():

// 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 * 10, 0 );
  DosSleep( 10 );                       // Allow the thread to finish.
}

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 that it uses a library call, despite the warnings above.

// file: hello_doscreate.c++
#include <iostream>

#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 );   // Allow the thread to finish
}

References