pthread create error in c++ [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
pthread Function from a Class
I am getting an error ("Can not convert .....") and I think the third argument in the pthread_create call is wrong. I know the type of the third argument should be (void*)*(void *) but I am still getting an error.
void ServerManager::Init(){
pthread_t thread;
pthread_create(&thread, NULL, AcceptLoop, (void *)this);
}
I have declared like this and I am trying to call the function below
void* ServerManager::AcceptLoop(void * delegate){
}
Please let me know how to fix this..
Thanks in advance.

To be portable the callback function must use the C ABI;
extern "C" void* AcceptLoop(void*);
class ServerManager
{
public:
void Init();
private:
friend void* AcceptLoop(void*);
void* AcceptLoop(); // Implement this yourself
pthread_t thread;
};
void ServerManager::Init()
{
pthread_create(&thread, NULL, &AcceptLoop, reinterpret_cast<void*>(this));
}
void* AcceptLoop(void* delegate)
{
return reinterpret_cast<ServerManager*>(delegate)->AcceptLoop();
}
void* ServerManager::AcceptLoop()
{
// Do stuff
// Be carefull this may (or may not) start before ServerManager::Init() returns.
return NULL;
}
Edit: Based on comment
pthread_join()
This will wait for a particular thread to exit. The thread that called pthread_create() can call pthread_join() to wait for the child to finish. A good place for this would(might) be to put the join in the destructor of the ServerManager.
pthread_cancel()
pthread_cancel() is an asynchronous request for the thread to stop. The call will return immediately (thus does not mean the thread is dead yet). It is unspecified how quickily it will stop executing your code but it should execute some tidy handlers and then exit. It is a good idea to wait for a cancelled thread using pthread_jon().
class ServerManager
{
public:
void ~ServerManager()
{
join();
}
void* join()
{
void* result;
pthread_join(thread, &result);
return result;
}
void cancel()
{
pthread_cancel(thread);
join();
}
... like before
};

You need to make your AcceptLoop(void*) a static function.
Example:
class ServerManager {
// ...
static void* AcceptLoop(void*);
void* AcceptLoop(); // Implement this yourself
};
void* ServerManager::AcceptLoop(void* delegate)
{
return static_cast<ServerManager*>(delegate)->AcceptLoop();
}

Related

Cannot kill std::thread

I have a program that I need to run a thread in. The problem is whenever I try to kill this thread from either inside the thread or outside the thread I get a "error 6 - invalid handle" error
class myclass
{
public:
static myclass* inst()
{
if (oInst == nullptr) oInst = new myclass;
return oInst;
};
void main();
void start();
void ex_stop()
{
//HANDLE Stopper = Killer.native_handle();
//TerminateThread(Stopper, 0);
}
}
private:
std::thread Killer;
}
void myclass::start()
{
Killer = std::thread(&myclass::ex_main, this);
Killer.detach();
}
void myclass::main()
{
...
if (0 == TerminateThread(Killer.native_handle(), 0))
{
char error[200];
sprintf(error, "error %i\n", GetLastError());
printf(error);
}
This is how I start the class/thread
myclass::inst()->start();
I've also tried making std::thread Killer an extern and declaring it in my .cpp and .h files, this way I can access it from outside the class, but I still get the same "error 6, invalid thread handle" error.
Can someone please tell me what's wrong with this code? Thanks
The usual way of having a worker thread set up is to put it into a loop, and on each loop check to see if a boolean atomic has been changed ... something that would look like (but this probably doesn't compile straight off; the threadMain will probably need binding)
class myThreadJob {
public:
myThreadJob():
doRun(true),
thread(threadMain)
{}
void threadMain() {
while (doRun) {...}
}
void stop() {
doRun = false;
thread.join();
}
private:
std::atomic<bool> doRun;
std::thread thread;
}
You've not said if your thread is a will do many tasks in a queue, or if it's a one off job that it's doing, but in any case if it's expected to be a long lived thread, it should check periodically that it can still run.
Because you've called detach() on your thread, your thread is no longer associated with your process. You can think of detach() as a declaration that the thread does not need anything local to the creating thread.
You are not allowed to join it; and you're expecting it to run to termination.

Can I use a pointer assignment to detect the start of a thread in a safe way?

I quickly wrote some kind of wrapper to ensure some functionality in a system is always executed in a defined thread context. To make the code as small as possible, I simple use a pointer assignment to check if the thread has started.
void waitForStart() {
while (_handler == nullptr) {
msleep(100); // Sleep for 100ms;
}
msleep(100); // Sleep for 100ms to make sure the pointer is assigned
}
In my opinion, this should work in any case. Even if the assignment to _handler is for unknown reason split up into two operations on a CPU.
Is my assumtion correct? Or did I miss a case where this could go wrong?
For reference a more complete example how the system looks like. There are the System, the Thread and the Handler classes:
class Handler {
public:
void doSomeWork() {
// things are executed here.
}
};
class Thread : public ThreadFromAFramework {
public:
Thread() : _handler(nullptr) {
}
void waitForStart() {
while (_handler == nullptr) {
msleep(100); // Sleep for 100ms;
}
msleep(100); // Sleep for 100ms to make sure the pointer is assigned
}
Handler* handler() const {
return _handler;
}
protected:
virtual void run() { // This method is executed as a new thread
_handler = new Handler();
exec(); // This will go into a event loop
delete _handler;
_handler = nullptr;
}
private:
Handler *_handler;
}
class System {
public:
System() {
_thread = new Thread();
_thread->start(); // Start the thread, this will call run() in the new thread
_thread->waitForStart(); // Make sure we can access the handler.
}
void doSomeWork() {
Handler *handler = _thread->handler();
// "Magically" call doSomeWork() in the context of the thread.
}
private:
Thread *_thread;
}
You missed a case where this can go wrong. The thread might exit 5 msec after it sets the pointer. Accessing any changing variable from two threads is never reliable without synchronization.

Unable to receive a message using message_queue in Boost thread

I have a requirement for creating a Event based Multi-thread application for which i am trying to use boost::thread and boost/interprocess/ipc/message_queue for sending messages between threads.
What i am doing currently is making the thread wait in its workerfunction to wait for a message.
Actually this is just for basic start where the sender and receiver both is a same thread, on later stage i have thought to store a list of message_queue corresponding for each thread and then fetch it accordingly or something like that.
But now, as per the code below i am using
//in a common class
typedef struct s_Request{
int id;
}st_Request;
//in thread(XYZ) class
st_Request dataone;
message_queue *mq;
void XYZ::threadfunc(void *ptr)
{
XYZ*obj = (XYZ*) ptr;
obj->RecieveMsg();
}
void XYZ::RecieveMsg()
{
message_queue mq1(open_only,"message_queue");
if(!(mq1.try_receive(&dataone, sizeof(st_Request), recvd_size, priority)))
printf("msg not received");
printf("id = %d",dataone.id);
}
void XYZ::Create()
{
mq= new message_queue(open_or_create,"message_queue",100,sizeof(st_Request));
boost:thread workerthread(threadfunc,this);
workerthread.join();
}
void XYZ::Send(st_Request *data)
{
if (!(mq->try_send(data, sizeof(st_Request), 0)))
printf("message sending failed");
}
//I am calling it like
class ABC: public XYZ
{
..some functions to do stuff... };
void ABC::createMSGQ()
{
create();
st_Request *data;
data->id =10;
send(data);
}
My thread is waiting in RecieveMsg but i am not getting any msg and the prints are coming till Send function entry and than the code crash.
Please Guide me for what i am doing wrong, if the approach is entirely wrong, i am open to move to new approach.
P.s. this is my first question on stack overflow i tried follow the guidelines still if i strayed away anywhere please do correct.
st_Request *data;
data->id =10;
data is uninitialized, you cannot dereference it. Pointers should point to something before you dereference them.
I don't understand the point of this function:
void XYZ::Create()
{
mq= new message_queue(open_or_create,"message_queue",100,sizeof(st_Request));
boost:thread workerthread(threadfunc,this);
workerthread.join();
}
You create a new thread, then block and wait for it to finish so you can join it. Why not just do the work here, instead of creating a new thread and waiting for it to finish?
What is threadfunc? Do you mean ThreadFunc?
This function is written strangely:
void XYZ::ThreadFunc(void *ptr)
{
XYZ*obj = (XYZ*) ptr;
obj->RecieveMsg();
}
Why not pass the argument as XYZ* instead of void*? Boost.Thread doesn't require everything to be passed as void*. Is that function static? It doesn't need to be:
struct XYZ {
void threadFunc();
void create();
void recv();
};
void XYZ::threadFunc()
{
recv();
}
void XYZ::create()
{
boost::thread thr(&XYZ::threadFunc, this);
thr.join();
}

C++ Class: Object that creates Thread + pointer to the function = Access violation

I am very surprised by the strange exception, that I got.
class Threads {
public:
Threads() {}
~Threads() {}
void StartThread(int (*p)()); //pointer to a function
private:
HANDLE hThread;
DWORD dwThreadID;
};
Method StartThread should receive pointer to my function (that will be run in another thread).
This function is simple. (as you can see it is situated outside the class Threads):
int MyThread()
{
return 0;
}
And this is method of creating thread:
inline void Threads::StartThread(int (*p)())
{
hThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)(*p)(),
NULL,
0,
&dwThreadID);
if (hThread == NULL)
{
return;
}
}
Here compiler get error: cannot convert parameter 3 from 'int' to 'LPTHREAD_START_ROUTINE'. That why I did the casting.
In main function I create object of type Threads and I try to call method StartThread. As parameter I send pointer to the function MyThread.
Threads *thread1;
thread1 = new Threads();
thread1->StartThread(MyThread);
I thought MyThread must start in another thread. But the function MyTread always runs in Main Thread!!! And only after MyThread ends, another thread starts and then I get this exception:
Unhandled exception at 0x00000000 in ThreadClass.exe: 0xC0000005: Access violation.
I need clever advice!
The call convention is wrong:
LPTHREAD_START_ROUTINE is a __stdcall method not a __cdecl method, see the documentation here: http://msdn.microsoft.com/en-us/library/aa964928.aspx.
It looks like you are actually calling the function on this line...
(LPTHREAD_START_ROUTINE)(*p)()
...and it returns an int that you're casting. That just can't work. How about:
(LPTHREAD_START_ROUTINE)p
...instead?

c++ multithread

I use C++ to implement a thread class. My code shows in the following.
I have a problem about how to access thread data.
In the class Thread, I create a thread use pthread_create() function. then it calls EntryPoint() function to start thread created. In the Run function, I want to access the mask variable, it always shows segment fault.
So, my question is whether the new created thread copy the data in original class? How to access the thread own data?
class Thread {
public:
int mask;
pthread_t thread;
Thread( int );
void start();
static void * EntryPoint (void *);
void Run();
};
Thread::Thread( int a) {
mask =a;
}
void Thread::Run() {
cout<<"thread begin to run" <<endl;
cout << mask <<endl; // it always show segmentfault here
}
void * Thread::EntryPoint(void * pthis) {
cout << "entry" <<endl;
Thread *pt = (Thread *) pthis;
pt->Run();
}
void Thread::start() {
pthread_create(&thread, NULL, EntryPoint, (void *)ThreadId );
pthread_join(thread, NULL);
}
int main() {
int input_array[8]={3,1,2,5,6,8,7,4};
Thread t1(1);
t1.start();
}
I'm not familiar with the libraries you're using, but how does EntryPoint know that pthis is a pointer to Thread? Thread (this) does not appear to be passed to pthread_create.
It's great that you're attempting to write a Thread class for educational purposes. However, if you're not, why reinvent the wheel?
pThis is most likely NULL, you should double check that you're passing the correct arguments to pthread_create.
Basically, the problem is as soon as you start your thread, main exits and your local Thread instance goes out of scope. So, because the lifetime of your thread object is controlled by another thread, you've already introduced a race condition.
Also, I'd consider joining a thread immediately after you've created it in Thread::start to be a little odd.