ibm-information-center/dist/eclipse/plugins/i5OS.ic.apis_5.4.0.1/concept8.htm

169 lines
5.6 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Copyright" content="Copyright (c) 2006 by IBM Corporation">
<title>Thread creation using C++ methods as target does not work</title>
<!-- Begin Header Records ========================================== -->
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<!-- Change History: -->
<!-- YYMMDD USERID Change description -->
<!-- NETMG2 SCRIPT A converted by B2H R4.1 (346) (CMS) by HOLTJM at -->
<!-- RCHVMW2 on 29 Jan 1999 at 10:01:37 -->
<!--File Edited November 2001 -->
<!--End Header Records -->
<link rel="stylesheet" type="text/css" href="../rzahg/ic.css">
</head>
<body>
<!-- Java sync-link -->
<script language="Javascript" src="../rzahg/synch.js" type="text/javascript">
</script>
<a name="Top_Of_Page"></a>
<h2>Thread creation using C++ methods as target does not work</h2>
<p>Often, as a C++ programmer, you may want to abstract the concept of a thread
into a C++ class. To do this, you must realize that the Pthread APIs are C
language APIs. The Pthread APIs use functions that have C linkage and calling
conventions. For your application to successfully use the pthread functions,
you must provide helper functions of the appropriate type and linkage for the
Pthread APIs that take function pointers as parameters.</p>
<p>When sharing objects between threads, always be aware of which thread is
manipulating the object, which thread is responsible for freeing the object,
and what thread safety issues are created by sharing objects between
threads.</p>
<p>The following example shows how to successfully create a program that
abstracts a thread into a C++ class. It can be easily extended to provide a
mechanism by which the thread creation and manipulation itself is also
encapsulated into the class.</p>
<br>
<h3>Example</h3>
<p>See <a href="../apiref/aboutapis.htm#codedisclaimer">Code disclaimer information</a>
for information pertaining to code examples.</p>
<pre>
/* This C++ example must be compiled with VisualAge C++ for OS/400 */
#define _MULTI_THREADED
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stddef.h&gt;
#include &lt;pthread.h&gt;
class ThreadClass {
public:
ThreadClass(char *s) {
data1 = 42; data2 = strlen(s);
strncpy(str, s, sizeof(str)-1);
str[49]=0;
}
void *run(void);
private:
int data1;
int data2;
char str[50];
};
extern "C" void *ThreadStartup(void *);
int main(int argc, char **argv)
{
ThreadClass *t=NULL;
pthread_t thread;
int rc;
// Use printf instead of cout.
// At the time this test was written, the C++ standard class library
// was not thread safe.
printf("Entered test %s\n", argv[0]);
printf("Create a ThreadClass object\n");
t = new ThreadClass("Testing C++ object/thread creation\n");
printf("Start a real thread to process the ThreadClass object\n");
// #define COMPILE_ERROR
#ifdef COMPILE_ERROR
// This is an ERROR. You cannot create a thread by using a pointer
// to a member function. Thread creation requires a C linkage function.
// If you remove the comments from the line `#define COMPILE_ERROR'
// the compiler will give a message similar to this:
// "ATESTCPP0.C", line 46.53: 1540-055: (S) "void*(ThreadClass::*)()"
// cannot be converted to "extern "C" void*(*)(void*)".
rc = pthread_create(&amp;thread, NULL, ThreadClass::run, NULL);
#else
// Instead, this is the correct way to start a thread on a C++ object
rc = pthread_create(&amp;thread, NULL, ThreadStartup, t);
#endif
if (rc) {
printf("Failed to create a thread\n");
exit(EXIT_FAILURE);
}
printf("Waiting for thread to complete\n");
rc = pthread_join(thread, NULL);
if (rc) {
printf("Failed to join to the thread, rc=%d\n");
exit(EXIT_FAILURE);
}
printf("Testcase complete\n");
exit(EXIT_SUCCESS);
}
// This function is a helper function. It has normal C linkage, and is
// as the base for newly created ThreadClass objects. It runs the
// run method on the ThreadClass object passed to it (as a void *).
// After the ThreadClass method completes normally (i.e returns),
// we delete the object.
void *ThreadStartup(void *_tgtObject) {
ThreadClass *tgtObject = (ThreadClass *)_tgtObject;
printf("Running thread object in a new thread\n");
void *threadResult = tgtObject-&gt;run();
printf("Deleting object\n");
delete tgtObject;
return threadResult;
}
void *ThreadClass::run(void)
{
printf("Entered the thread for object %.8x %.8x %.8x %.8x\n", this);
printf("Object identity: %d, %d: %s\n", data1, data2, str);
return NULL;
}
</pre>
<p><strong>Output</strong></p>
<pre>
Entered test QP0WTEST/ACPPOBJ
Create a ThreadClass object
Start a real thread to process the ThreadClass object
Waiting for thread to complete
Running thread object in a new thread
Entered the thread for object 80000000 00000000 d017dad2 57001f60
Object identity: 42, 35: Testing C++ object/thread creation
Deleting object
Testcase complete
</pre>
<hr>
<center>
<table cellpadding="2" cellspacing="2">
<tr align="center">
<td valign="middle" align="center">
<a href="#Top_Of_Page">Top</a> |
<a href="rzah4mst.htm">Pthread APIs</a> |
<a href="aplist.htm">APIs by category</a></td>
</tr>
</table>
</center>
</body>
</html>