Getting error when using pthread_create [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
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]

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.

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 );

If you declare the function static it will compile.

Related

Cpp: How to create a thread with method that requires pointer? [duplicate]

This question already has answers here:
std::thread pass by reference calls copy constructor
(2 answers)
Closed 4 years ago.
I want to create a thread that will automatically join after the work is done. So, I wrote the fallowing code:
#include <iostream>
#include <thread>
#include <chrono>
#include <future>
using namespace std;
class Foo
{
public:
void work(atomic_bool & isWorking);
};
void Foo::work(atomic_bool & isWorking)
{
//dosomestuff;
int myVar = 0;
while (myVar != 5)
{
myVar++;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
isWorking = true;
return;
}
int main()
{
std::atomic<bool> imdone;
imdone = false;
std::thread t1(&Foo::work, Foo(), imdone);
while (true)
{
std::cout << "Is Joinable: " << t1.joinable() << "\n";
if (imdone)
{
imdone = false;
t1.join();
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
cin.get();
}
I thought that I can pass argument like this: std::thread t1(&Foo::work, Foo(), imdone);, but not in case when the argument is a pointer. How am I supose to pass a pointer in this situation?
You create an object of the type whose member you want to call and pass its address like this:
Foo foo; // create an object
std::thread t1(&Foo::work, &foo, ...); // pass its address
In addition you are passing a reference so you need to use std::ref like this:
Foo foo; // create an object
std::thread t1(&Foo::work, &foo, std::ref(imdone)); // use std::ref()

C++ Threading with Boost Library

I want my function running in a separate thread. I use Boost library and include like this in my main.cpp:
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
I want the thread start like this:
boost::thread ethread(Engine::function,info);
// info is an object from the class Engine and i need this in the
// function
My Engine class is in the func.h and the function looks like this:
void Engine::function(Engine info)
{
//STUFF
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
}
BTW: Is the sleep function for the thread right?
Every time I want to compile it gives me this error:
error C3867: "Engine::function": function call missing argument list; use '&Engine::function' to create a pointer to member
I tried to use &Engine::function in the thread and this error appears:
error C2064: term does not evaluate to a function taking 2 arguments
I also tried:
boost::thread ethread(Engine::function,info, _1);
Then this error appeared:
error C2784: "result_traits<R,F>::type boost::_bi::list0::operator [](const boost::_bi::bind_t<R,F,L> &) const"
Can someone help me with this? I only want to run the function beside the main thread.
You should use bind function to create functional object with pointer to class member function or make your function static.
http://ru.cppreference.com/w/cpp/utility/functional/bind
More detailed explanation:
boost::thread constructor needs pointer to a function. In case of normal functions syntax is simple: &hello
#include <boost/thread/thread.hpp>
#include <iostream>
void hello()
{
std::cout << "Hello world, I'm a thread!" << std::endl;
}
int main(int argc, char* argv[])
{
boost::thread thrd(&hello);
thrd.join();
return 0;
}
But if you need pointer to a function of class you have to remember that such functions have implicit parameter - this pointer, so you have to pass it also. You can do this by creating callable object with std::bind, or boost bind.
#include <iostream>
#include <boost/thread.hpp>
class Foo{
public:
void print( int a )
{
std::cout << a << std::endl;
}
};
int main(int argc, char *argv[])
{
Foo foo;
boost::thread t( std::bind( &Foo::print, &foo, 5 ) );
t.join();
return 0;
}

C++11 multithreading with class member function [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 7 years ago.
I want to use multithreading in C++11 to call a class member function in its own thread. I have been able to get this to work with a global function:
#include <thread>
#include <iostream>
void Alpha(int x)
{
while (true)
{
std::cout << x << std::endl;
}
}
int main()
{
std::thread alpha_thread(Alpha, 5);
alpha_thread.join();
return 0;
}
However, I cannot get it to compile with a class member function:
#include <thread>
#include <iostream>
class Beta
{
public:
void Gamma(int y)
{
while (true)
{
std::cout << y << std::endl;
}
}
};
int main()
{
Beta my_beta;
std::thread gamma_thread(my_beta.Gamma, 5);
gamma_thread.join();
return 0;
}
The compile error is:
no matching function for call to 'std::thread::thread(<unresolved overloaded function type>)'
std::thread gamma_thread(my_beta.Gamma, 5);
^
What am I doing wrong?
You need to pass two things: a pointer-to-member, and the object. You cannot call a non-static member function (like Gamma) in C++ without an object. The correct syntax would be:
std::thread gamma_thread(&Beta::Gamma, // the pointer-to-member
my_beta, // the object, could also be a pointer
5); // the argument
You can think of my_beta here as being the first argument to Gamma(), and 5 as the second.
You need to name the function, then pass the object on which to call it as an explicit implicit this parameter. :)
std::thread gamma_thread(&Beta::Gamma, my_beta, 5);
This is a bit of an abstraction leak, granted.
You have multiple problems in your program
As your compile error says, you need to pass the address of the function &Beta::Gamma.
You need to pass the object as a parameter considering this is an implicit parameter of a member function
Modified source
#include <thread>
#include <iostream>
class Beta
{
public:
void Gamma(int y)
{
while (true)
{
std::cout << y << std::endl;
}
}
};
int main()
{
Beta my_beta;
std::thread gamma_thread(&Beta::Gamma, my_beta, 5);
gamma_thread.join();
return 0;
}

Using functor in pthread_create

What this code do:
Several commands executed to completion(if(current seconds == some seconds) stop).
CommandProcessor(functor) run this commands. Pointer of this class I try to throw to pthread_create.
The question:
It is possible to use class object as callable?
command.h
#ifndef COMMAND_H
#define COMMAND_H
#include <iostream>
#include "commandprocessor.h"
class CommandProcessor;
using namespace std;
class Command
{
static CommandProcessor *commandProcessor;
time_t stopSeconds;
public:
Command(int _stopSeconds);
static void setProcessor(CommandProcessor *_commandProcessor);
void execute();
};
#endif // COMMAND_H
command.cpp
#include "command.h"
CommandProcessor* Command::commandProcessor = NULL;
Command::Command(int _stopSeconds)
{
stopSeconds = _stopSeconds;
}
void Command::setProcessor(CommandProcessor *_commandProcessor)
{
commandProcessor = _commandProcessor;
}
void Command::execute()
{
time_t seconds;
time_t now = time(NULL);
seconds = localtime(&now)->tm_sec;
cout << seconds << endl;
if(seconds != stopSeconds)
commandProcessor->addCommand(this);
}
commandprocessor.h
#ifndef COMMANDPROCESSOR_H
#define COMMANDPROCESSOR_H
#include <list>
#include "command.h"
using namespace std;
class Command;
class CommandProcessor
{
list< Command* > commandsList;
public:
void addCommand(Command *_command);
void operator()();
};
#endif // COMMANDPROCESSOR_H
commandprocessor.cpp
#include "commandprocessor.h"
void CommandProcessor::addCommand(Command *_command)
{
commandsList.push_back(_command);
}
void CommandProcessor::operator()()
{
while(commandsList.size() > 0)
{
Command *command = commandsList.front();
commandsList.pop_front();
command->execute();
}
}
main.cpp
#include <iostream>
#include <pthread.h>
#include "commandprocessor.h"
#define MAX_THREADS 2
using namespace std;
int main(int argc, char **args)
{
CommandProcessor *processor = new CommandProcessor();
Command::setProcessor(processor);
processor->addCommand(new Command(53));
processor->addCommand(new Command(24));
processor->addCommand(new Command(15));
pthread_t threads[MAX_THREADS];
for(int i=0; i < MAX_THREADS; i++)
{
pthread_create(&threads[i], NULL, processor(), NULL); // error: 'processor' cannot be used as a function
}
return 0;
}
DISCLAIMER : this is the kind of thing that you really shouldn't be doing in C++, as it includes messing around with void*. It needs to be used here because of the interaction with the C API. If you can, use std::thread from C++11 or boost::thread if you're using an older compiler.
To answer your question : yes, it is perfectly fine to make a class object as a callable (as a "function") once you implement operator() for it. You already did that, but the problem is the extra code needed to implement the interface between C++ and the C API for Pthreads.
The main reason why you're getting the "processor cannot be used as a function" error here is because processor is a CommandProcessor* and, as such, needs a dereference. However, even doing (*processor)() wouldn't help you, because pthread_create is defined as follows :
int pthread_create(phread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
This means that the function to be executed must return void* and take a void*. The documentation also states that the parameter of start_routine has the value of arg originally given to the respective call to pthread_create.
However, you cannot pass a pointer to CommandProcessor::operator()() to pthread_create for a much more important reason : it is a member function. All non-static class member functions need to be called with an object so that they can refer to this inside their body.
The solution to your problem is to make a static function that will match the prototype required by pthread_create, and pass the pointer to a CommandProcessor as the arg of pthread_create. Have a look at this :
static void* processor_executor(void *arg)
{
CommandProcessor *processor = static_cast<CommandProcessor*>(arg);
(*processor)();
return NULL;
}
int main(int argc, char **argv)
{
/* ... */
for(int i=0; i < MAX_THREADS; i++)
{
pthread_create(&threads[i], NULL, processor_executor, static_cast<void*> (processor));
}
/* ... */
}
This way, operator() is executed inside the thread created by pthread_create, using the same CommandProcessor object as the one in main().
Keep in mind that accessing the same data from within many parallel threads will lead to data races. Use mutexes, semaphores, or condition variables to protect the data from parallel access.

C++ thread conversion error [duplicate]

This question already has answers here:
pthread function from a class
(9 answers)
Closed 9 years ago.
I'm from Colombia so the error is in Spanish. This seems the fastest place to get an answer...
I've been trying to make a simple program that creates threads and saves the information in a vector but when I build the code the next error appears:
...Lanzador.cpp|19|error: no se puede convertir ‘void* (Hilo::*)(void*)’ a ‘void* (*)(void*)’ para el argumento ‘3’ para ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’|
I have three files: the header for Hilos that says:
#ifndef HILO_H
#define HILO_H
using namespace std;
class Hilo
{
public:
Hilo();
virtual ~Hilo();
void addHilo(int);
void* ImprimirHilo(void*);
protected:
private:
};
#endif // HILO_H
Hilo.cpp that says:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include "Hilo.h"
using namespace std;
vector<int> info (1);
Hilo::Hilo()
{
//ctor
}
Hilo::~Hilo()
{
//dtor
}
void Hilo::addHilo(int tiempo){
info.push_back(tiempo);
}
void* Hilo::ImprimirHilo(void *threadid)
{
long tid;
tid = (long) threadid;
int n =info.at(tid);
for (int i=n; i>0; i-- ){
info.at(tid)=i;
cout << "El hilo numero: " << tid << " tiene " << i <<" segundos"<< endl;
sleep(1);
}
pthread_exit(NULL);
}
And the class that has the main Lanzador.cpp
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include "Hilo.h"
using namespace std;
int main (){
Hilo h;
pthread_t threads;
int tiempo=0;
int rc;
int contador=0;
cout << "Para salir oprima 0 \n"<<endl;
cout << "Escriba el tiempo del hilo" << endl;
while (true){
cin >> tiempo;
if (tiempo>0){
contador++;
h.addHilo(tiempo);
rc = pthread_create(&threads, NULL,&h.ImprimirHilo, (void*)contador);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
}
pthread_exit(NULL);
}
I hope that you people can help me. Sorry for the bad English and thanks for the help
Based on the signatures mentioned in the error message you are trying to use a member function where a void() function or pointer thereof is needed: using a member function directly won't work! You need to realize that a member function apparently taking no argument actually does have a hidden argument: the this pointer! Thus, an object needs to be provided. Since you use pthread_create() there isn't any way around that: you need to come up with a normal function taking no arguments. Since the function probably needs to be declared extern "C" you can't use a static member function either.
Something doesn't seem right, however, as pthread_create() actually takes a void*(*)(void*) as argument, not a void*(*)(void) as is claimed in the error message: the void* can be used to pass information to the thread entry function, e.g., a pointer to an object which could be restored to the correct type before calling a suitable member function.
You cannot use non static methods in threading.
You will have to use the following pattern to get an instance aware method multi-threaded.
baseclass.h
class baseclass
{
int a;
static void __stdcall threaded(void* params);
}
baseclass.cpp
void __stdcall
threaded(void* params)
{
// this is your class instance
pThis = static_cast<baseclass*>(params);
printf("%d", pThis->a);
}
main.cpp
// class instance is entered as the parameter
rc = pthread_create(&threads, NULL, Hilo::ImprimirHilo, (void*)&h);