Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

same function name form different classes used in pthread

Posted on 2008-10-20
5
873 Views
Last Modified: 2012-05-05
I try to implement multi-threading on Linux using C/C++ using pthread, but got a question:
how can I use the same function name from two different classes in the pthread's pthread_create?

more precisely:
I have two classes by using a template, so they are:
==============================================================
class buyerA {
order(item);
pay(total);
}

class buyerB {
order(item);
pay(total);
}
==============================================================
now I like use the pthread library, how can I create threads for these two buyers?
can I do (assume A is one instance of Class A, and B is another instance of ClassB):
==============================================================
pthread_create(pt1, NULL, A.order(), NULL, item1);
pthread_create(pt2, NULL, B.order(), NULL, item2);

....

pthread_create(pt1, NULL, A.pay(), NULL, total1);
pthread_create(pt2, NULL, B.pay(), NULL, total2);

.....
=================================================

Thanks for the help.
0
Comment
Question by:cw1592
  • 2
  • 2
5 Comments
 
LVL 45

Assisted Solution

by:sunnycoder
sunnycoder earned 100 total points
ID: 22764512
The approach you are exploring is not very common. You might be better off spawning threads from main and instantiating A and B in the threads. However, the approach you are seeking is feasible using static functions. Something like


#include <pthread.h>
#include <stdio.h>
 
class A {
    public:
    static void * ret_val (void *) { printf ("A.val\n"); return NULL; }
};
 
 
class B {
    public:
    static void * ret_val (void *) { printf("B.val\n"); return NULL; }
};
 
    typedef void * (*fn)(void *);
int main ()
{
    A a; B b;
    pthread_t t1,t2;
    pthread_create(&t1, NULL, static_cast<fn>(a.ret_val),NULL);
    pthread_create(&t2, NULL, static_cast<fn>(b.ret_val),NULL);
    pthread_join(t1,NULL);
    pthread_join(t2,NULL);
}

Open in new window

0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 400 total points
ID: 22766839
>>>>    pthread_create(&t1, NULL, static_cast<fn>(a.ret_val),NULL);

You better would do

    pthread_create(&t1, NULL, A::ret_val, &a);
    pthread_create(&t1, NULL, B::ret_val, &b);

(it avoids to making things look more difficult than they are).

When passing the object to the thread, you can cast the void pointer to its original known type like that:

   static void * A::ret_val (void * p)
   {
        A* pA = (A*)p;
        pA->dosomething();
        return NULL;
  }

Note, dosomething usually is a non-static member function.

In case you want to have only one thread function for both A and B, you might consider to derive A and B from a common baseclass. Then, the static function can be a member of the baseclass, the cast was made for a baseclass pointer and the dosomething was a virtual function overloaded by class A and B so that depending on passing a or b the thread virtually calls the appropriate member function virtually.

Note, template classes are not suitable for the above approach as the template type must be determined at compile time. So, when passing objects from type A or B where A and B where template classes from the same template, you can't find out in the thread function which type was passed. You also would need a common  baseclass where you virtually could ask which type to take

   static void * Base::ret_val (void * p)
   {
        Base* pBase = (Base*)p;
        if (pBase->getTypeId() == 1)
        {
              A* pA = (A*)p;
              pA->dosomething();
        }
        else if (pBase->getTypeId() == 2)
        {
              B* pB = (B*)p;
              pB->dosomething();
        }
        return NULL;
  }

what is not very elegant and the thread function must *know* all types it should handle.


 
0
 

Author Comment

by:cw1592
ID: 22770294
thanks for the comments; maybe I should use the Boost libray?can I do something like:

boost::thread* pThread = new boost::thread(
    boost::bind(
    &ClassA::ret_val,             // member function
    &theClassA) );              // instance of class

could you advice on which approach will be better (pthres or boost) in this situtaiton where a tmeplate is used to get more than one class, and threas are generated based on the member funcitons in classes (from the virtual funcitons from the tamplate)?
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 400 total points
ID: 22771248
pthread is a C (function) library for threading purposes while boost is a mighty C++ class library, so both concepts not really were comparable. Problem of boost is that it is not always available in existing projects (I actually never had a project - out of perhaps 20 in the last ten years - where boost was involved or even was discussed). And of course the usage of a big class library not automatically makes you a better programmer or writes software without own efforts. You would need to gain experience using the library before you could expect any benefits (a fool with a tool is still a fool). For the design question whether to go with templates or with a virtual approach, it is less important whether to go with pthread or boost. Generally, templates were good for containers and helpers (utilities) as you have to write code only once for numerous types. Derivation and virtual concepts is an OOP thing, i. e. it asks how you look onto your data in a logical object-oriented way (not a technical one).  So, normally you have a mix. For the complex objects you were using a virtual class design and for the containers, helpers, aand utilities you were using templates. For the latter there are good and reliable template libraries from STL to boost and you actually have no need to develop own template classes (normally).
0
 

Author Comment

by:cw1592
ID: 22824649
thanks to all, these comments help.
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question