I am using structures in C++, and i try to save pointers in that structures, but when i try to use that structure in a thread i cant get the data of the structure.
struct threadData {
void* memPointer;
void* instructionPointer;
void* stackPointer;
int memsize;
};
void *worker_thread(void *arg) {
struct threadData *my_data;
my_data = (struct threadData *) arg;
cout<<"INSTRUCTION POINTER: "<<my_data->instructionPointer<<endl;
cout<<"MEMORY POINTER: "<<my_data->memPointer<<endl;
cout<<"STACK POINTER: "<<my_data->stackPointer<<endl;
cout<<"MEMORY SIZE: "<<my_data->memsize<<endl;
}
int main() {
pthread_t my_thread;
int ret;
struct threadData td = { calloc(1, 32), calloc(1000000, 64), calloc(34, 4),6475 };
ret = pthread_create(&my_thread, NULL, worker_thread, (void *) &td);
pthread_detach(my_thread);
//pthread_exit(NULL);
}
But when i use pthread_exit(NULL) after pthread_detach i can use the information of the structure in the method "worker_thread".
Since td is allocated on the stack in main, it gets clobbered by some clean-up code that the runtime executes after you return from main. Allocate your td struct on the heap instead of on the stack, and it will work as expected:
struct threadData tdVal = { calloc(1, 32), calloc(1000000, 64), calloc(34, 4),6475 };
struct threadData *td = malloc(sizeof(*td));
*td = tdVal;
// ...
ret = pthread_create(&my_thread, NULL, worker_thread, (void *) td);
However, you still have a problem. Returning from main will kill the other pthreads in your program. Since there's no synchronization in your code preventing main from completing before worker_thread is run, you can't even guarantee that worker_thread will run at all.
You should probably not detach the worker thread, and instead use pthread_join to make sure it has completed before returning from main. Also note that if you ensure main does not return before worker_thread completes, then there's no problem with leaving td on the stack.
Without pthread_exit, you are returning from main, and the local variable td is destroyed before the other threads are completed.
By calling pthread_exit, you force the main thread to wait for the other threads to complete, so td doesn't get destroyed too early.
As #Aconcagua noticed, the documentation for pthread_exit says that the calling thread is terminated. It doesn't make an exception for the main thread, so at least in principle, the main thread's stack could disappear while the other threads were still executing. This means that even with the call to pthread_exit, you have undefined behavior.
Related
I'm reading the source code of a project, which is developed with C++98 on Linux.
There is such a piece of code:
class Test {
public:
Test();
static void func(void *arg) {
pthread_detach(pthread_self());
Test *obj = (Test*)arg;
// do something
}
};
Test::Test() {
pthread_t tid; // ???
pthread_create(&tid, NULL, Test::func, this);
}
This is quite clear: a thread is created in the constructor of Test, which calls the function func, and this thread would be detached.
But I'm worrying about pthread_t tid;. When the construcor returns, the variable tid, as a local variable, should be released. Am I right? However, we have passed its address as the first parameter of pthread_create.
Will it cause some lifetime issue, such as a segment fault?
When you call pthread_create, it saves the ID of the thread in tid.
It doesn't save the address of tid. It just puts the ID there before it returns.
So there is no problem.
However, if this bothers you, you should call pthread_detach(tid) in Test::Test instead of pthread_detach(pthread_self()) inside the thread.
It is allowed for a thread to detach itself, but it is slightly strange, because the purpose of pthread_detach is to tell the system that nobody is going to wait for this thread (by calling pthread_join), so the thread can be destroyed as soon as it finishes. Usually, whoever is creating the thread decides whether to wait for it or not - not the thread itself.
I'm working through some simple pthread examples form llnl.computing.gov pthreads tutorial. The program on the website prints out the address of the threadid, but I would like to pass the address of the id to PrintHello, and then use dereference the address to get the id. I think with the sleep in there every thread should print 8 (the number of threads). The code is
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NUM_THREADS 8
void *PrintHello(void *threadid)
{
long *taskid = (long *)threadid;
sleep(1);
printf("Hello from thread %ld\n", *taskid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0;t<NUM_THREADS;t++) {
printf("Creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
When I compile and run this in Cygwin it seg faults with stack corruption errors. If I rewrite PrintHello as:
void *PrintHello(void *threadid)
{
long taskid = (long) threadid;
sleep(1);
printf("Hello from thread %ld\n", taskid);
pthread_exit(NULL);
}
it doesn't seg fault, it just prints the address and I would like to dereference the address and get the value of t from main.
Does anyone have some pointers on how to accomplish that goal? I know I can pass t to pthread_create instead of &t but I want to do it this way for learning purposes.
When you call pthread_exit(NULL) from the main thread, it terminates that thread. At that point, any local variables in the main function, including t, are destroyed and can no longer be used.
If the main thread exits before all of your worker threads are finished using t (via the pointer you pass to them via pthread_create), your program exhibits undefined behavior.
The program contains a race condition because the access of the variable t from the worker threads and the destruction of the variable t from the main thread are unsynchronized. One way to fix this problem would be to have the main thread join with each of the worker threads (via pthread_join) before it exits.
1) you pass the address of t so every thread will get a pointer to the same variable, that's not the thread ID, it's a long which has a value that keeps changing. You are modifying the variable in main and reading it in each other thread, which is a data race.
2) Probably what happens is that by the time the new threads execute the loop in main has finished and the variable has gone out of scope. When main exits its local variables will be popped off the stack, so when the other threads access t it is no longer on the stack. You don't have any synchronisation in your program to prevent that, so you have another data race there. You need to wait in main for the threads to finish, which you can do by calling pthread_join to wait for each one, but that still won't change the fact the other threads are trying to read a variable while it's being written to by another thread.
3) There's no need to call pthread_exit there, returning from the function or from main automatically exits the thread (just like calling exit(0) causes main() to finish)
Some pointers? Well, you have plenty of them in your thread functions...
The problem: you can't safely pass around the address of your local variable - it gets out of scope when main exits. You'll need to either declare the pointer as a static global variable, or malloc() sizeof(long) bytes of memory and use that.
How do you close a thread, when you done? like making sure nothing is open anymore or runing?
so far i know how to open it, but .. not how to close it right
int iret1;
pthread_t thread1;
char *message1;
void *multithreading1( void *ptr ) {
while (1) {
// Our function here
}
}
int main (int argc, char * const argv[]) {
if( (iret1=pthread_create( &thread1, NULL, multithreading1, (void*) message1)) )
{
printf("Thread creation failed: %d\n", iret1);
}
return 0;
}
"How do you close a thread, when you done?"
Either by just simple returning from that function or calling pthread_exit function.
Note that calling return also causes the stack to be unwound and variables declared within start routine to be destroyed, thus it's more preferable than pthread_exit function:
An implicit call to pthread_exit() is made when a thread other than the thread in
which main() was first invoked returns from the start routine that was used to
create it. The function's return value shall serve as the thread's exit status.
For more information also have a look at: return() versus pthread_exit() in pthread start functions
"making sure nothing is open anymore or runing"
Instead of making sure whether your thread is still running, you should wait for its termination by using pthread_join function.
Here's an example:
void *routine(void *ptr) {
int* arg = (int*) ptr; // in C, explicit type cast is redundant
printf("changing %d to 7\n", *arg);
*arg = 7;
return ptr;
}
int main(int argc, char * const argv[]) {
pthread_t thread1;
int arg = 3;
pthread_create(&thread1, NULL, routine, (void*) &arg);
int* retval;
pthread_join(thread1, (void**) &retval);
printf("thread1 returned %d\n", *retval);
return 0;
}
output
changing 3 to 7
thread1 returned 7
To do this, you either return from the thread function (multithreading1) or call pthread_exit().
For more information, see POSIX Threads Programming.
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.
Let's have the following class definition:
CThread::CThread ()
{
this->hThread = NULL;
this->hThreadId = 0;
this->hMainThread = ::GetCurrentThread ();
this->hMainThreadId = ::GetCurrentThreadId ();
this->Timeout = 2000; //milliseconds
}
CThread::~CThread ()
{
//waiting for the thread to terminate
if (this->hThread) {
if (::WaitForSingleObject (this->hThread, this->Timeout) == WAIT_TIMEOUT)
::TerminateThread (this->hThread, 1);
::CloseHandle (this->hThread);
}
}
//*********************************************************
//working method
//*********************************************************
unsigned long CThread::Process (void* parameter)
{
//a mechanism for terminating thread should be implemented
//not allowing the method to be run from the main thread
if (::GetCurrentThreadId () == this->hMainThreadId)
return 0;
else {
m_pMyPointer = new MyClass(...);
// my class successfully works here in another thread
return 0;
}
}
//*********************************************************
//creates the thread
//*********************************************************
bool CThread::CreateThread ()
{
if (!this->IsCreated ()) {
param* this_param = new param;
this_param->pThread = this;
this->hThread = ::CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))this->runProcess, (void *)(this_param), 0, &this->hThreadId);
return this->hThread ? true : false;
}
return false;
}
//*********************************************************
//creates the thread
//*********************************************************
int CThread::runProcess (void* Param)
{
CThread* thread;
thread = (CThread*)((param*)Param)->pThread;
delete ((param*)Param);
return thread->Process (0);
}
MyClass* CThread::getMyPointer() {
return m_pMyPointer;
}
In the main program, we have the following:
void main(void) {
CThread thread;
thread.CreateThread();
MyClass* myPointer = thread.getMyPointer();
myPointer->someMethod(); // CRASH, BOOM, BANG!!!!
}
At the moment the myPointer is used ( in the main thread ) it crashes. I don't know how to get the pointer, which points to memory, allocated in another thread. Is this actually possible?
The memory space for your application is accessible to all threads. By default any variable is visible to any thread regardless of context (the only exception would be variables declared __delcspec(thread) )
You are getting a crash due to a race condition. The thread you just created hasn't started running yet at the point where you call getMyPointer. You need to add some kind of synchronization between the newly created thread and the originating thread. In other words, the originating thread has to wait until the new thread signals it that it has created the object.
I'm trying to get my head around what you are trying to do. It looks overly complicated for something like a thread-class. Would you mind post the class-definition as well?
Start by removing the C-style cast of the process-argument to CreateThread():
this->hThread = ::CreateThread (NULL, 0,&runProcess, (void *)(this_param), 0, &this->hThreadId);
If this doesn't compile you're doing something wrong! Never ever cast a function pointer! If the compiler complains you need to change your function, not try to cast away the errors! Really! You'll only make it worse for yourself! If you do it again they* will come to your home and do ... Let's see how you like that! Seriously, don't do it again.
Btw, in Process() I think it would be more appropriate to do something like:
assert(::GetCurrentThreadId() == hThreadId);
But if you declare it private it should only be accessible by your CThread-class anyway and therefor it shouldn't be a problem. Asserts are good though!
*It's not clear who they are but it's clear whatever they do it won't be pleasant!
As Rob Walker pointed out - I really missed the race condition. Also the crash is not when getting the pointer, but when using it.
A simple wait did the job:
MyClass* myPointer = thread.getMyPointer();
while (myPointer == 0)
{
::Sleep(1000);
}
myPointer->someMethod(); // Working :)