1

Possible Duplicate:
pthread Function from a Class

I am fairly new to c++ and I am doing a project regarding TCP.

I need to create a thread so I googled and found this. http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

I follow its syntax but encounter errors: argument of type ‘void* (ns3::TcpSocketBase::)()’ does not match ‘void* ()(void)’

codes:

tcp-socket-base.h:
class TcpSocketBase : public TcpSocket
{
 public:
 ...
 void *threadfunction();
 ....
}




tcp-socket-base.cc:

void
*TcpSocketBase::threadfunction()
{
//do something
}



..//the thread was create and the function is called here
pthread_t t1;
int temp  =  pthread_create(&t1, NULL, ReceivedSpecialAck, NULL); //The error happens here
return;
...

Any help would be appreciated. Thanks!

EDIT:

I took the advise and make the threadfunction a non member function.

namespaceXXX{

void *threadfunction()


int result  =  pthread_create(&t1, NULL, threadfunction, NULL);
      NS_LOG_LOGIC ("TcpSocketBase " << this << " Create Thread returned result: " << result );

void *threadfunction()
{
 .....
}


}

But I got this error instead:

initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* ()(void), void*)’ [-fpermissive]

Community
  • 1
  • 1
user1701840
  • 1,062
  • 3
  • 19
  • 27

3 Answers3

2

You look to be passing a member function of a class to your pthread_create function. The thread function should be a non-member function that has the following signature

void *thread_function( void *ptr );
mathematician1975
  • 21,161
  • 6
  • 59
  • 101
  • Does that mean I shouldn't declare threadfunction in my header file? – user1701840 Oct 29 '12 at 19:49
  • thats right. In the tutorial you are following you can see an example that uses a function that is not a member function. A member function requires an instance of a class to call it on (unless its a static member function). Try using a standalone function that is not a member function of a class. See the link to the duplicate question in the comments to your question – mathematician1975 Oct 29 '12 at 19:51
  • What happen if my threadfunction need to call some functions from the class ? – user1701840 Oct 29 '12 at 19:59
  • You can pass items to your thread function via the `void *arg` parameter in `pthread_create`. You could use this to pass a pointer to an instance of your class – mathematician1975 Oct 29 '12 at 20:07
  • But the threadfunction is going to have a loop that call an member function to check its values every few second. Does this still work? – user1701840 Oct 29 '12 at 20:11
  • you call a member function on an instance of that class. if you provide an instance of the class for the thread function to call it on it should work but I cannot say for sure without seeing your code. I would suggest reading the tutorial a few times to really get an understanding how the pthreads library works. – mathematician1975 Oct 29 '12 at 20:15
2

If you'd like to continue using pthreads, a simple example is:

#include <cstdio>
#include <string>
#include <iostream>

#include <pthread.h>

void* print(void* data)
{
    std::cout << *((std::string*)data) << "\n";
    return NULL; // We could return data here if we wanted to
}

int main()
{
    std::string message = "Hello, pthreads!";
    pthread_t threadHandle;
    pthread_create(&threadHandle, NULL, &print, &message);
    // Wait for the thread to finish, then exit
    pthread_join(threadHandle, NULL);
    return 0;
}

A better alternative, if you're able to, is to use the new C++11 thread library. It's a simpler, RAII interface that uses templates so that you can pass any function to a thread, including class member functions (see this thread).

Then, the above exmaple simplifies to this:

#include <cstdio>
#include <string>
#include <iostream>

#include <thread>

void print(std::string message)
{
    std::cout << message << "\n";
}

int main()
{
    std::string message = "Hello, C++11 threads!";
    std::thread t(&print, message);
    t.join();
    return 0;
}

Note how you can just pass data directly in - casts to and from void* are not needed.

Community
  • 1
  • 1
Matt Kline
  • 10,149
  • 7
  • 50
  • 87
  • thanks for your help. But I got this error: invalid conversion from ‘void (*)()’ to ‘void* (*)(void*)’ [-fpermissive] – user1701840 Oct 29 '12 at 21:01
  • I fixed my example so that it can compile. The function you pass to `pthread_create` takes a void pointer as an argument, allowing you to pass data into the thread. – Matt Kline Oct 29 '12 at 21:03
  • shouldn't it be (void *date)? – user1701840 Oct 29 '12 at 21:07
  • I changed it to (void \*date), and still got error on conversion. Error: void (*)(void*)’ to ‘void* (*)(void*). So I add '*' in front of the implementation and prototype of the threadfunction. And this error is gone, but I got another error:no return statement in function returning non-void [-Werror=return-type] – user1701840 Oct 29 '12 at 21:09
  • `void* data`, `void *data`, and `void*data` are all the same the compiler. C and C++ generally ignore whitespace. `data` is a void pointer - that is, it can point to anything, be it an integer, a floating point variable, or even a struct or class. To use it, you cast it back into the correct pointer type and dereference it. – Matt Kline Oct 29 '12 at 21:12
  • Sorry, I forgot that the return value of a function you pass to `pthread_create` must also be `void*`. This is so you can return data from the thread if you wish to do so (you can retrieve it with the second argument of `pthread_join`. – Matt Kline Oct 29 '12 at 21:23
  • Keep in mind that `std::thread` will make copies of arguments you pass to it. If you want to pass data by reference, use [`std::ref`](http://en.cppreference.com/w/cpp/utility/functional/ref) (and of course, make the arguments for the function you pass to `std::thread` pass-by-reference. – Matt Kline Oct 29 '12 at 21:30
  • Just one more question. Can the thread_create use a class function? – user1701840 Oct 29 '12 at 21:44
  • `pthread_create` can only take a class function if it is static, in which case you cannot access any class data in the function. `std::thread` can take class functions - see [this thread](http://stackoverflow.com/questions/10673585/start-thread-with-member-function). – Matt Kline Oct 29 '12 at 21:49
0

If you declare the function static it will compile.

guilespi
  • 4,672
  • 1
  • 15
  • 24