I'm having troubles with creation of the function, that should handle new thread. When I create it outside of the class, everything works allright, but when I want to create it inside a class, I can't realize, how to call it.
I call the function with:
pthread_t thread;
pthread_create(&thread, NULL,
sendMessage, (void *) fd);
and the function itself looks like this:
void * sendMessage(void *threadid) {
string message;
const char * c;
char buffer[200];
int fd = (long) threadid;
while (true) {
cin >> message;
if (message == "exit") {
break;
}
c = message.c_str();
strncpy(buffer, c, sizeof ( buffer));
send(fd, buffer, strlen(buffer), 0);
}
}
but when I declare it within a class e.g. void * Client::sendMessage(void *threadid) , I can't even build it because I get main.cpp:90:37: error: argument of type ‘void* (Client::)(void*)’ does not match ‘void* (*)(void*)’ Does anybody have any idea, what can cause it and how to fix it?
Just a quick demonstration of how std::thread can quickly make all your woes disappear (by seemlessly integrating with std::bind style invocation):
#include <string>
#include <thread>
#include <memory>
void some_function(int i, std::string bla)
{
}
struct some_class
{
void some_member_function(double x) const
{
}
};
int main()
{
std::thread t1(&some_function, 42, "the answer");
std::thread t2;
{
some_class instance;
t2 = std::thread(&some_class::some_member_function,
std::ref(instance),
3.14159);
t2.join(); // need to join before `instance` goes out of scope
}
{
auto managed = std::make_shared<some_class>();
t2 = std::thread([managed]()
{
managed->some_member_function(3.14159);
});
// `managed` lives on
}
if (t1.joinable()) t1.join();
if (t2.joinable()) t2.join();
}
Related
I have a such a requirement that:-
1) There are two class, say Wrapper and Wrapper2.
2) Wrapper2 contains reference object of class Wrapper.
3) A thread will write data to a variable of class Wrapper which should be essentially be calling a member function of Wrapper.
4) Another thread can read and write data to class member of Wrapper and this thread essentially be called through Wrapper2.
Based on some answers on older question on Stackoverflow, i created an example code to check why my production code is failing and i am not able to figure out the problem. As soon as thread2 is created it receives SIGSEG signals. Code is below:-
#include <thread>
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <wait.h>
#include <string.h>
pthread_mutex_t mt1;
void thread_signal(int signum)
{
pthread_exit(0);
}
void sig_func(int sig)
{
write(1, "Caught signal 11\n", 17);
std::cout<<"Caught signal :"<<sig<<std::endl;
signal(SIGSEGV,sig_func);
thread_signal(sig);
}
class Wrapper {
public:
Wrapper():i(10)
{
std::cout<<"Wrapper Constructor Called. "<<this<<" \n";
}
~Wrapper()
{
std::cout<<"Wrapper Destructor Called. "<<this<<"\n";
}
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
void setI(int i)
{
pthread_mutex_lock(&mt1);
this->i=i;
std::cout<<"set: "<< this->i<<std::endl;
pthread_mutex_unlock(&mt1);
}
int getI()
{
pthread_mutex_lock(&mt1);
std::cout<<"get: "<< this->i<<std::endl;
pthread_mutex_unlock(&mt1);
return 0;
}
int i;
};
class Wrapper2
{
public:
Wrapper2(Wrapper & wp):wp2(wp)
{
std::cout<<"Wrapper2 Constructor Called. "<<this<<" \n";
}
~Wrapper2()
{
std::cout<<"Wrapper2 Destructor Called. "<<this<<" \n";
}
Wrapper & wp2;
};
struct ThreadWrapper {
Wrapper & wr1;
Wrapper2 & wr2;
ThreadWrapper( Wrapper & wr1,Wrapper2& wr2):
wr1(wr1),wr2(wr2)
{
}
};
extern "C" void* wrapper1Fun ( void* wr1)
{
std::auto_ptr< Wrapper > wrp1 ( static_cast< Wrapper* >( wr1 ) );
std::cout<<"Thread 1 created. \n";
while(1)
{
wrp1->setI(rand()%100);
usleep(50);
}
return 0;
}
extern "C" void* wrapper2Fun ( void* wr2)
{
std::auto_ptr< Wrapper2 > wrp2 ( static_cast< Wrapper2* >( wr2 ) );
std::cout<<"Thread 2 created. \n";
while(1)
{
wrp2->wp2.getI();
usleep(50);
}
return 0;
}
int main(int argc, char **argv) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = thread_signal;
sa.sa_flags = 0;
sigaction(SIGTERM, &sa, 0);
bool mainRunning= true;
Wrapper w;
Wrapper2 w1(w);
sleep(1);
ThreadWrapper * myWrap = new ThreadWrapper(w,w1);
sleep(1);
pthread_t pt1;
pthread_t pt2;
pthread_attr_t attr;
signal(SIGSEGV,sig_func); // Register signal handler before going multithread
pthread_attr_init(&attr);
int i = pthread_create(&pt1, NULL,wrapper1Fun, myWrap);
std::cout<<"First thread status "<<i<<std::endl;
sleep(1);
int j = pthread_create(&pt2, &attr,wrapper2Fun, myWrap);
std::cout<<"Second thread status "<<j<<std::endl;
sleep(1);
while(1);
fprintf(stderr, "kill thread\n");
//pthread_kill(pt1, SIGTERM);
fprintf(stderr, "join thread\n");
pthread_join(pt1, NULL);
pthread_join(pt1, NULL);
return 0;
}
wrapper1Fun expects to be passed a pointer to a Wrapper, and wrapper2Fun expects to be passed a pointer to a Wraper2. But you're actually passing a pointer to a ThreadWrapper to each, which is a completely different type, so it goes wrong.
The use of void * and casts prevents the compiler from pointing out your type error. I would suggest using a type safe C++ threading library rather than raw pthread. Boost has one, as does the standard library from C++11.
Also your use of auto_ptr is questionable at best. It's deprecated, easy to get wrong, and a poor way of expressing ownership - prefer unique_ptr or shared_ptr.
Here you construct two auto_ptr values owning the same pointer, so it will be freed twice, which is undefined behaviour.
In any case there's no obvious reason to put any of these objects on the heap. If you do, you need to decide where the ownership of the memory resides.
I am trying to do a threaded application to infinitely print a set of numbers after enqueing them. I get this error:
Error 1 error C3867: 'Test::ThreadFunc': function call missing argument list; use '&Test::ThreadFunc' to create a pointer to member.
What am I doing wrong? What is the mistake ?
#include "stdafx.h"
#include <chrono>
#include <mutex>
#include <thread>
#include <list>
class Test {
std::list<int> queue;
std::mutex m;
public:
void ThreadFunc()
{
// Loop is required, otherwise thread will exit
for (;;)
{
bool read = false;
int value;
{
std::lock_guard<std::mutex> lock(m);
if (queue.size())
{
value = queue.front();
read = true;
queue.pop_back();
}
}
if (read)
{
// send(header.data(), header.dataSize());
// send(proto.data(), proto.dataSize());
printf("Hello %d\n", value);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void TestFunc()
{
std::thread thread(ThreadFunc);
thread.detach();
int i = 0;
// Loops only as a test example
for (;;)
{
std::lock_guard<std::mutex> lock(m);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
queue.push_back(i++);
// Queue Message(header, payload);
}
}
};
int main()
{
Test test;
test.TestFunc();
}
You're attempting to pass a pointer to a member function of a class. When you do this, there's an argument added to the function, tacitly, that is a pointer to the instance of the class that you're invoking the function on. In your case, the pointer to the class will be the this pointer.
See this for syntax reference: Start thread with member function
To answer your comment, why isn't it passed implicitly? You're not calling the function as a member of a class, you're passing the member function by pointer. This is a different, unique, situation, see this reference: Passing a member function as an argument in C++
Also, to save a little future headache, the next problem that comes up is that std::thread's constructor takes its arguments by value, so if you need to pass any arguments by reference, take a look at std::ref.
Here's the fix. This works. Thank you #mock_blatt
#include "stdafx.h"
#include <chrono>
#include <mutex>
#include <thread>
#include <list>
class Test {
std::list<int> queue;
std::mutex m;
public:
void ThreadFunc()
{
// Loop is required, otherwise thread will exit
for (;;)
{
bool read = false;
int value;
{
std::lock_guard<std::mutex> lock(m);
if (queue.size())
{
value = queue.front();
read = true;
queue.pop_back();
}
}
if (read)
{
// send(header.data(), header.dataSize());
// send(proto.data(), proto.dataSize());
printf("Hello %d\n", value);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
void TestFunc()
{
std::thread thread(std::bind(&Test::ThreadFunc, this));
thread.detach();
int i = 0;
// Loops only as a test example
for (;;)
{
std::lock_guard<std::mutex> lock(m);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
queue.push_back(i++);
// Queue Message(header, payload);
}
}
};
int main()
{
Test test;
test.TestFunc();
}
Change std::thread thread(ThreadFunc); to std::thread thread(Test::ThreadFunc, this);
I am new to C++, and I have started doing multi-threading in C++. Can you please comment on the following program? Is it a right way of using mutex? The other question is to identify the shared resource in C++ is easy - just look at static members. C++ doesn't have the concept of global variables, and therefore we can just look at the static members of a class? Afterwards, decide what should be serialized - mutex locked/unlocked? In C, it is a bit challenge to identify the shared resources, as there is a concept of global variables. Can you correct me on my understanding?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
/** get pid **/
#include <sys/types.h>
#include <unistd.h>
using namespace std;
class helium_thread
{
private:
pthread_t *thread_id;
public:
static pthread_mutex_t mutex_thread;
void set_thread_id(pthread_t tid);
pthread_t *get_thread_id();
int create_thread(pthread_t *thread_ptr, const pthread_attr_t *attr, void * (*start_routine)(void *), void *arg );
helium_thread();
~helium_thread();
};
void helium_thread::set_thread_id( pthread_t tid)
{
*(this->thread_id) = tid;
}
pthread_t * helium_thread::get_thread_id( )
{
return (this->thread_id);
}
int helium_thread::create_thread(pthread_t *thread_ptr, const pthread_attr_t *attr, void * (*start_routine)(void *), void *arg )
{
int ret;
ret = pthread_create(thread_ptr,attr,start_routine,(void *)arg) ;
cout<<"Thread created "<<std::hex<<thread_ptr<<endl;
return ret;
}
helium_thread::helium_thread()
{
thread_id = new pthread_t;
cout<<"Constructor called "<<std::hex<<thread_id<<endl;
}
helium_thread::~helium_thread()
{
cout<<"Destructor called"<<std::hex<<thread_id<<endl;
delete thread_id;
}
/** While defining the methods of the class, Keywords static and virtual should not be repeated in the definition. **/
/** They should only be used in the class declaration. **/
void *Thread_Function(void *thread_arg)
{
pthread_mutex_lock(&(helium_thread::mutex_thread));
cout<<"Inside Thread_Function"<<endl;
pid_t *thread_pid_val = (pid_t *) thread_arg;
/** std::hex will print the value isn hexadecimal **/
cout<<"The process pid is "<< std::hex << (*thread_pid_val) <<endl;
pthread_t ptid = pthread_self();
cout<<" The thread id is " << std::hex<< ptid << endl;
pthread_mutex_unlock(&(helium_thread::mutex_thread));
}
/** The definition of the static member can't be inside a function, You need to put it outside **/
/** When I tried using inside a function, I got the error - error: invalid use of qualified-name ‘helium_thread::mutex_thread **/
pthread_mutex_t helium_thread::mutex_thread = PTHREAD_MUTEX_INITIALIZER;
int main(int argc, char *argv[])
{
helium_thread thread_1, thread_2;
pid_t thread_pid_val = getpid();
pthread_t thread_1_id;
thread_1.create_thread((thread_1.get_thread_id()),NULL,Thread_Function,&thread_pid_val);
thread_2.create_thread((thread_2.get_thread_id()),NULL,Thread_Function,&thread_pid_val);
pthread_join( *(thread_1.get_thread_id()), NULL);
pthread_join( *(thread_2.get_thread_id()), NULL);
return 0;
}
A few things:
Globals can be used in C++ but try to avoid them, especially in multithreaded code.
You didn't initialize or destroy the mutex anywhere.
In C++ you should not call mutex_lock/unlock directly but have a wrapper class do it for you, to avoid keeping the mutex locked on an early return from the function (return on error or exception).
Example:
class auto_lock {
pthread_mutex_t* mutex;
public:
auto_lock(pthread_mutex_t* _mutex) : mutex(_mutex) {
if (mutex) pthread_mutex_lock(mutex);
}
~auto_lock(){
if (mutex) pthread_mutex_unlock(mutex);
}
};
I have a problem with threading a not static method from a singleton class,look at the code :
//g++ main.cc -lpthread
#include<iostream>
#include<unistd.h>
#include<pthread.h>
class SLAYER{
private:
SLAYER(){};
~SLAYER(){};
static SLAYER *singleton;
pthread_t t1, t2;
public:
static void *born(){
singleton = new SLAYER;
};
static void *death(){
delete singleton;
singleton = NULL;
};
static void *start(){
pthread_create(&singleton->t1,NULL,singleton->KerryRayKing, NULL);
pthread_create(&singleton->t2,NULL,singleton->JeffHanneman, NULL);
};
void *JeffHanneman(void *arg){
sleep(1);
std::cout << "(1964-2013) R.I.P.\n";
(void) arg;
pthread_exit(NULL);
};
static void *KerryRayKing(void *arg){
sleep(1);
std::cout << "(1964-still with us) bald\n";
(void) arg;
pthread_exit(NULL);
};
};
SLAYER *SLAYER::singleton=NULL;
int main(){
SLAYER::born();
SLAYER::start();
std::cout << "thread started\n";
sleep(5);
SLAYER::death();
return 0;
}
as you can see KerryRayKing() is static unlike JeffHanneman(). I failed to pass JeffHanneman() to pthread_create(), at compilation time I got :
cannot convert ‘SLAYER::JeffHanneman’ from type ‘void* (SLAYER::)(void*)’ to type ‘void* (*)(void*)’
I tried several cast, but failed... isn't possible to use in this cas a non static method ?
edit :
I forgot to say, I don't want to allow access to JeffHanneman() from outside
Short answer: you can't do that.
There are several workarounds, the simplest is to have static wrapper function, e.g.
static void *JHWrapper(void *self)
{
SLAYER *that = static_cast<SLAYER*>(self);
return that->JeffHanneman();
}
void *JeffHanneman(){ // Note "arg" removed.
sleep(1);
std::cout << "(1964-2013) R.I.P.\n";
pthread_exit(NULL);
};
Now, the pthread create becomes:
pthread_create(&singleton->t1,NULL, SLAYER::JHWrapper, static_cast<void *>(singleton));
[I refrained from the pun of "JHRapper", as I think that would be rather demeaning...]
I am very new to C++.
I have a class, and I want to create a thread inside a class's function. And that thread(function) will call and access the class function and variable as well.
At the beginning I tried to use Pthread, but only work outside a class, if I want to access the class function/variable I got an out of scope error.
I take a look at Boost/thread but it is not desirable because of I don't want to add any other library to my files(for other reason).
I did some research and cannot find any useful answers.
Please give some examples to guide me. Thank you so much!
Attempt using pthread(but I dont know how to deal with the situation I stated above):
#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;
}
You can pass a static member function to a pthread, and an instance of an object as its argument. The idiom goes something like this:
class Parallel
{
private:
pthread_t thread;
static void * staticEntryPoint(void * c);
void entryPoint();
public:
void start();
};
void Parallel::start()
{
pthread_create(&thread, NULL, Parallel::staticEntryPoint, this);
}
void * Parallel::staticEntryPoint(void * c)
{
((Parallel *) c)->entryPoint();
return NULL;
}
void Parallel::entryPoint()
{
// thread body
}
This is a pthread example. You can probably adapt it to use a std::thread without much difficulty.
#include <thread>
#include <string>
#include <iostream>
class Class
{
public:
Class(const std::string& s) : m_data(s) { }
~Class() { m_thread.join(); }
void runThread() { m_thread = std::thread(&Class::print, this); }
private:
std::string m_data;
std::thread m_thread;
void print() const { std::cout << m_data << '\n'; }
};
int main()
{
Class c("Hello, world!");
c.runThread();
}