3

I know the thread routine that is passed to pthread_create API has the prototype of

void *threadproc(void *).

I was just wondering if it is possible to use a C++ function object as a thread routine.

Here's my code:

Execution::run method takes a time_t variable and a functor as parameters. It spawns a POSIX thread in which it spins until the scheduled run time is current and runs some job.

#include <pthread.h>
#include <ctime>
#include <unistd.h>
#include <iostream>
using namespace std;

class ThreadFunctor
{
public:
  void *operator()(time_t runTime)
  {
      time_t curTime;
      double timeDiff;

      time(&curTime);
      timeDiff = difftime(runTime, curTime);

      if (timeDiff > 0)
      {
          sleep(timeDiff);
      }

      //
      // doSomething();
      //

      return NULL;
  }
};

class Execution
{
public:
  Execution() {}
  int run(time_t scheduledTime, ThreadFunctor &threadProc)
  {
      int rc = pthread_create(&mThread, NULL, threadProc, &scheduledTime);
      if (rc != 0)
      {
          cerr << "Thread creation failed\n";
          return -1;
      }
      return 0;
  }

private:
  pthread_t mThread;
};

Questions:

  1. Can I use a function object as thread function? How?

  2. How do I pass parameters to the operator() method of the function object?

  3. In this code, the parent process terminates while the child thread is still running. Because we don't want to block the caller of run() method. Is this a good practice? Will the orphan thread cause problem here?

Thanks.

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
itnovice
  • 503
  • 1
  • 4
  • 20
  • 8
    Before diving into this (and to let you know, most of what you're asking is possible), is using the [**C++11 Thread Support Library**](http://en.cppreference.com/w/cpp/thread) an option for you? If so, you may want to skip the pthread intermediary and go straight to the winner's circle, because it honestly rocks. – WhozCraig Oct 17 '14 at 06:56
  • @WhozCraig: Can I pass functor type to std::thread constructor? Thanks – itnovice Oct 17 '14 at 16:25
  • 1
    Yes, and in fact anything "callable" can either directly, or with a very minimal effort, be turned into a thread-able entity. The C++11 thread support library is quite-frankly *oozing* with yummy goodness. ex: Coupled with [`std::bind`](http://en.cppreference.com/w/cpp/utility/functional/bind) it makes threading object member invokes *trivial*. I could sing its praises from the mountain tops for hours, and cannot advise strongly enough that you investigate whether it is available for your target platforms. If it is, *use it*. – WhozCraig Oct 17 '14 at 16:32
  • 1
    Your first question boils down to "Can I convert a functor to a function pointer?" and the answer is no. You could pass the object as a `void*` and use an according function for the function part. The rest should follow or be easy to figure out, but you should read what WhozCraig, because it's good advise and a much better approach. – Ulrich Eckhardt Oct 17 '14 at 17:27

1 Answers1

3

A pthread function must have C linkage, so it cannot be a member function. Strictly speaking, it cannot even be a static member function, even though that will work almost all the time.

So what should be done is to create a non-member function that takes a void* argument that will be a pointer to the C++ object to be the thread function. That function can cast the void* argument to a class pointer, which calls the member function.

See In C++, is it safe/portable to use static member function pointer for C API callbacks?

Community
  • 1
  • 1
Michael Burr
  • 333,147
  • 50
  • 533
  • 760