Archived

This topic is now archived and is closed to further replies.

Dipp

Linux +Thread problem

Recommended Posts

I have tried to do a little program that creates a thread, in Gnu/Linux but it comnplains about a pointer thing that I have no clue about. The error is as follows: (Sorry for the smiley in the error but it should be a : instead of it)
threadtimer.cpp:50: error: argument of type `void*(CTest::)(void*)' does not match `void*(*)(void*)'
 
And here is the code:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

class CTest
{
	public:
		void *Printmess(void*);
};

void *CTest::Printmess(void *id)
{
	cout << "Hello World!" << endl;
}

int main(int argc, char *argv[])
{
	CTest test;
	pthread_t trad;
	int rc, t;
	
	cout << "Creating thread..." << endl;
	
	rc = pthread_create(&trad, NULL, test.Printmess, (void *)t);
	if(rc){
		cout << "Could not create thread!" << endl;
		return -1;
	}
	
	pthread_exit(NULL);
	
	
	return 0;
	
}
  
[edited by - dipp on May 19, 2004 7:31:10 AM] [Edit: Source tags work a little better than code tags, fixed smiley] [edited by - Magmai Kai Holmlor on May 19, 2004 10:51:43 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by fredizzimo
Declare Printmess as static.


Ok so i declared it as follows:

static void *Printmess(void*);

and the programs runs fine until it hits:

rc = pthread_create(&trad[t], NULL, test.Printmess, (void *)t);

And there it recieves segmentation fault.

Well here is the updated code:

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
#include <pthread.h>

using namespace std;

class CTest
{
public:
static void *Printmess(void*);
};

void *CTest:rintmess(void *id)
{
cout << id << ":Hello World!" << endl;
pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
CTest test;
pthread_t trad[5];
int rc, t;

for(t=0;t<5;t++){
cout << "Creating thread..." << t << endl;
rc = pthread_create(&trad[t], NULL, test.Printmess, (void *)t);
if(rc){
cout << "Could not create thread!" << endl;
return -1;
}
}

pthread_exit(NULL);


return 0;

}

Share this post


Link to post
Share on other sites
Pointer to (non-static) member function are not function pointer. Additionally, C++ doesn''t support passing bound methods around.

You will need to do something like:
void* Printmess_trampoline(void* object)
{
CTest& test = dynamic_cast<CTest&>(*object);
return test.Printmess();
}

rc = pthread_create(&trad, NULL, Printmess_trampoline, &test);


That is, if you want to call a member function, you must use the "user argument" parameter of pthread_create to pass a pointer to your object (or a struct containing that pointer as well as any argument you want to pass to the member function - in which case you would use a static_cast instead of a dynamic cast and pray that your user doesn''t mess up).


“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.”
— Brian W. Kernighan

Share this post


Link to post
Share on other sites
Yes, my fault, I haven''t actually used linux threads, so I didn''t know that the function need to use the extern "C" calling convention.

In other words, you have to use a non-member function, declared as extern "c", like this


extern "c" void* Printmess(void *id)
{
cout << id << ":Hello World!" << endl;
pthread_exit(NULL);
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
you should also be able to do the following:

class Posting
{
public:

static void* Post(void* arg) { printf("hi\n"; }

};

and later:

pthread_create(&trad[t], NULL, Posting:ost, (void *)t);

haven''t written pthread code in a couple years, but i seem to remember that working.

Share this post


Link to post
Share on other sites
quote:
Original post by Dipp

and the programs runs fine until it hits:

rc = pthread_create(&trad[t], NULL, test.Printmess, (void *)t);

And there it recieves segmentation fault.



Put -lpthread in your gcc args. Otherwise it can segmentation fault since it can''t find the function.

Share this post


Link to post
Share on other sites