169 lines
5.6 KiB
HTML
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 <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stddef.h>
|
||
|
#include <pthread.h>
|
||
|
|
||
|
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(&thread, NULL, ThreadClass::run, NULL);
|
||
|
#else
|
||
|
// Instead, this is the correct way to start a thread on a C++ object
|
||
|
rc = pthread_create(&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->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>
|
||
|
|