Solved

same function name form different classes used in pthread

Posted on 2008-10-20
5
885 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
[X]
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
  • 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…

705 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