473,385 Members | 1,838 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

How to pass a class-member function to pthread_create(....)?

Hi all:

I want to pass a class-member function to pthread_create, and my
code is in the following, but I don't know how to pass
myobj.thread_function to pthread_create function.

#include <pthread.h>
class test
{
public:
test(){}
~test(){}
void thread_function(void*){}

};

int main()
{
test myobj;

pthread_t thrd;

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

/************************************************** ************/
/* How to pass myobj.thread_function(NULL) to pthread_create(...)*/
pthread_create(&thrd, &attr, /*????????*/, NULL);
/************************************************** ************/

pthread_attr_destroy(&attr);

}

the pthread_create(...)'s Syntax

#include <pthread.h>;

int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void
*(*start_routine) (void *), void *arg) ;

Jul 23 '05 #1
12 38440
On Fri, 15 Jul 2005 12:07:19 +0400, <Hu*****@gmail.com> wrote:
Hi all:

I want to pass a class-member function to pthread_create, and my
code is in the following, but I don't know how to pass
myobj.thread_function to pthread_create function.


[]

See, pthread_create() takes a callback function pointer and a user void*
pointer which can be used for passing a pointer to an object. All you have
to do is to use little thunk as a thread start routine that directs the
control flow into a member function of the object.

#include <pthread.h>

class test
{
public:
test(){}
~test(){}
void thread_function(){}

};

template<class T, void(T::*mem_fn)()>
void* thunk(void* p)
{
(static_cast<T*>(p)->*mem_fn)();
return 0;
}

int main()
{
test myobj;

pthread_t thrd;

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

pthread_create(&thrd, &attr, thunk<test, &test::thread_function>,
&myobj);

pthread_attr_destroy(&attr);
}

--
Maxim Yegorushkin
<fi****************@gmail.com>
Jul 23 '05 #2
Ian
Hu*****@gmail.com wrote:
Hi all:

I want to pass a class-member function to pthread_create, and my
code is in the following, but I don't know how to pass
myobj.thread_function to pthread_create function.

You absolutely can't!

A C++ member function is not an extern "C" function as required for
pthread_create.

It my have different linkage and it also has a hidden this parameter, so
the signature is wrong.

Some environments will let you get away with a static member, but this
isn't portable.

Your best bet is to have the method to be called public and pass an
instance of the class as the arg parameter. The start_routine can then
cast it's parameter and call the member.

Don't forget to declare the start_routine as extern "C".

Ian

Jul 23 '05 #3
Ian
Maxim Yegorushkin wrote:
On Fri, 15 Jul 2005 12:07:19 +0400, <Hu*****@gmail.com> wrote:
Hi all:

I want to pass a class-member function to pthread_create, and my
code is in the following, but I don't know how to pass
myobj.thread_function to pthread_create function.

[]

See, pthread_create() takes a callback function pointer and a user
void* pointer which can be used for passing a pointer to an object. All
you have to do is to use little thunk as a thread start routine that
directs the control flow into a member function of the object.

#include <pthread.h>

class test
{
public:
test(){}
~test(){}
void thread_function(){}

};

template<class T, void(T::*mem_fn)()>
void* thunk(void* p)
{
(static_cast<T*>(p)->*mem_fn)();
return 0;
}

But a template can't be extern "C", as required by pthread_create.

Ian
Jul 23 '05 #4
On Fri, 15 Jul 2005 13:37:18 +0400, Ian <no***@nowhere.com> wrote:

[]
But a template can't be extern "C", as required by pthread_create.


That is true. In theory.

Could you please name the environment where this does not
compile/link/work?

--
Maxim Yegorushkin
<fi****************@gmail.com>
Jul 23 '05 #5
Ian
Maxim Yegorushkin wrote:
On Fri, 15 Jul 2005 13:37:18 +0400, Ian <no***@nowhere.com> wrote:

[]
But a template can't be extern "C", as required by pthread_create.

That is true. In theory.

Could you please name the environment where this does not
compile/link/work?

Sun CC gives a warning, but still works. I assume any reasonably
compliant compiler will issue a warning.

Ian
Jul 23 '05 #6


Hu*****@gmail.com wrote:
Hi all:

I want to pass a class-member function to pthread_create, and my
code is in the following, but I don't know how to pass
myobj.thread_function to pthread_create function.

#include <pthread.h>
class test
{
public:
test(){}
~test(){}
void thread_function(void*){}

};

int main()
{
test myobj;

pthread_t thrd;

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

/************************************************** ************/
/* How to pass myobj.thread_function(NULL) to pthread_create(...)*/
pthread_create(&thrd, &attr, /*????????*/, NULL);
/************************************************** ************/

pthread_attr_destroy(&attr);

}

the pthread_create(...)'s Syntax

#include <pthread.h>;

int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void
*(*start_routine) (void *), void *arg) ;


Perhaps this is not the most elegant solution, but I worked around this
by using a friend function along the lines of:

friend void* tfunc(void* args);

I then passed this friend function to the pthread_create(...) function,
casted the args value to my class name:

void* tfunc(void* args)
{
test* threadClass = (test*)args;
test->thread_function(0);
return 0;
}

This solutions doesn't let you pass along the void* args parameters,
but you can get around this by adding a member in your class that
stores the void* args to be retrieved once the thread is executed.

You then move thread_function() to be protected and have a
ThreadStart(void* args) or something along those lines that is called
to launch the thread.

-Collin

Jul 23 '05 #7
IIRC the DEC CXX compiler required the declaration of
the thread function before it was declared friend
in the Thread class: making the function static
in the class itself did not help.

Stephan

Jul 23 '05 #8
On 2005-07-15 09:07:19 +0100, Hu*****@gmail.com said:
I want to pass a class-member function to pthread_create ...


One key may be to not mix abstractions and not abuse inheritance.

A Thread class should really be some kind of "helper" that allows
you to execute _some code_ that is unrelated to the thread class
by itself, but is only required to run in some specific OS provided
thread of execution (irrespective of your Thread class)

In the simplest case, when you do want to abuse inheritance:

struct thread {
// stuff ommitted
virtual void
start() {
int code = ::pthread_create(
&handle
, &(attributes->get())
, pthread_main
, reinterpret_cast<void *>(this)) ;

if (code) throw int_exception(code) ;
}

// stuff ommitted
virtual void
run() {
}

// stuff ommitted
static void *
pthread_main(void * a) {
thread * t = reinterpret_cast<thread *>(a) ;
if (t) {
t->run() ;
}
return a ;
}
} ;

Now, if you do want to have your "runnables" and your thread class
be independent concepts & citizens, I 'd suggest you have a look
at this (still in progress) piece of work:

http://wiki.uiwithstyle.org/wiki.pl?...l_Object_Model

--
Do your users a favor: give them Style: http://www.uiwithstyle.org

Jul 23 '05 #9
Ian
verec wrote:

// stuff ommitted
static void *
pthread_main(void * a) {


Why do people keep using static members here when this is plain wrong?
Don't the compiler warnings tell you something?

Ian
Jul 23 '05 #10
On 2005-07-17 03:39:19 +0100, Ian <no***@nowhere.com> said:
Why do people keep using static members here when this is plain wrong?
Could you elaborate?
Don't the compiler warnings tell you something?


No. gcc 4.0, -Wall

--
JFB

Jul 23 '05 #11
Ian
verec wrote:
On 2005-07-17 03:39:19 +0100, Ian <no***@nowhere.com> said:
Why do people keep using static members here when this is plain wrong?

Could you elaborate?

pthread_create is a C function. The third parameter is

void* (*start_routine)(void*)

So when called from C++, this function has the signature

extern "C" void* (*start_routine)(void*)

Which doesn't match a static class member function.
Don't the compiler warnings tell you something?

No. gcc 4.0, -Wall

Well it should!

Ian
Jul 23 '05 #12
On 2005-07-17 05:35:48 +0100, Ian <no***@nowhere.com> said:
verec wrote:
On 2005-07-17 03:39:19 +0100, Ian <no***@nowhere.com> said:
Why do people keep using static members here when this is plain wrong?

Could you elaborate?

pthread_create is a C function. The third parameter is

void* (*start_routine)(void*)

So when called from C++, this function has the signature

extern "C" void* (*start_routine)(void*)

Which doesn't match a static class member function.


Hmmm. The only thing that would disqualify the static member
in this case is that its linkake is not declared ``extern "C"''.

But if we get down to the spirit of this linkage/ABI requirements
(as opposed to its strict letter), this static member function:
- takes a C style argument (a void *, that cannot be any of the
the more esoteric C++ types (references or polymorphic types)
- returns a C style argument (ditto)

So the only contention point might now reside with name mangling,
and indeed the mom::thread::pthread_main static member appears
as:

__ZN3mom6thread12pthread_mainEPv

I just don't see any _requirement_ in pthread (or anywhere else
for that matter!) that would restrict the kind of name that
a function, (extern "C" or otherwise) must have in order for
the actual link (and further down the road: loading & resolving)
to succeed, provided such a name is what common linkers/loaders
do expect.

Precisely, this whole name mangling business has been invented
by Stroustrup to make sure that linkers/loaders would unwittingly
cooperate.

I would tend to see this whole argument as wrong headed nit-picking,
until proven wrong by an actual refence to the relevant paragraph(s)
of the ISO-C++ document.

Beside this, exiting _practice_ has been using this idiom as far
back as C++ existed, precisely to help map OS defined callbacks
to the "object world of C++". I've been using this since around 1989
(Yep, I'm _that_ old :)
Don't the compiler warnings tell you something?

No. gcc 4.0, -Wall

Well it should!


Again: please quote the standard refence paragraph, and I'm sure
that the GCC developers will be more than willing to adapt.

(And I will be very sorry and will have to go through more convoluted
routes to achieve what is a basically a pointer to standard C function!)
--
JFB

Jul 23 '05 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Todd | last post by:
Is it possible to pass an argument by reference through an event in C++ managed code? For example, can I do the following? public __gc class MyClass : public Control { public: __event...
2
by: Tony Johansson | last post by:
Hello! I use method forName and newInstance in class Class like this instance = (GameFactory)(Class.forName(name).newInstance() ); Now to my question: Assume that name is GameFactory then I...
9
by: Jay Douglas | last post by:
Hello, I am needing to pass a class object (this) by reference to a method in a different class. When I do the following code I get the error (Cannot pass '<this>' as a ref or out argument because...
7
by: liyang3 | last post by:
Hi, I have Class A, B and C. Class A has an instance of B. Class B has an instance of C. In the instance of C, it generates some data that need to be passed back to Class A. But Class C...
3
by: Brett | last post by:
I have several classes that create arrays of data and have certain properties. Call them A thru D classes, which means there are four. I can call certain methods in each class and get back an...
6
by: kath | last post by:
hi everyone......... I have a task, I have fragmented the task into subtask. I have planned to create a class to each subclass and one parent class to handle the sub tasks. Each subclass are...
7
by: forest demon | last post by:
all i want is to do is to pass a form reference to a separate class and be able to manipulate properties/components/controls of said form. this should be as simple as passing a TextBox, Container...
24
by: =?Utf-8?B?U3dhcHB5?= | last post by:
Can anyone suggest me to pass more parameters other than two parameter for events like the following? Event: Onbutton_click(object sender, EventArgs e)" Event handler: button.Click += new...
12
by: raylopez99 | last post by:
Keywords: scope resolution, passing classes between parent and child forms, parameter constructor method, normal constructor, default constructor, forward reference, sharing classes between forms....
21
by: raylopez99 | last post by:
In the otherwise excellent book C# 3.0 in a Nutshell by Albahari et al. (3rd edition) (highly recommended--it's packed with information, and is a desktop reference book) the following statement is...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.