In my project I want to create thread which do nothing but append some string to textfile to test if it works. I'm using IDE Eclipse Juno on Ubuntu 12.04. Part of my code is:
pthread_t processThread;
threadData * thData = new threadData;
int t = pthread_create(&processThread, NULL,
BufferedData::processData, (void *)thData);
where threadData is struct with parameters for thread. Thread start member function of class BufferedData so processData method is static. Its declaration is:
static void * processData(void * arg);
After this part of code I check t value - the returning value of pthread_create. Everytime it is equals to 0 so I suppose that start of thread was succesful. But still it does nothing - it doesn't append string to file. It doesn't matter what function processData do: append string to file, throw exception, write to cout or something else. It does nothing everytime.
I'm not experienced C++ programmer so I don't know what to check, edit or do to solve the problem. IDE doesn't give me any response that something is wrong, it faces as everything is ok.
Thanks for your answers.
EDIT:
the code of processData function:
void * BufferedData::processData(void * arg) {
HelperFunctions h;
h.appendToFile("log", "test");
return 0;
}
appendToFile method write string "test" to file "log". This is tested in other projects and it works.
Now your thread will be finished in a time (not infinite), so this can help you :
int pthread_join(pthread_t thread, void **status);
In bellow code, when your thread created then pthread_join function waiting for a return from your thread. in this state use of pthread_exit() instead of return keyword.
Try this pthread_join() :
void *ret;
pthread_t processThread;
threadData * thData = new threadData;
int t = pthread_create(&processThread, NULL,
BufferedData::processData, (void *)thData);
if (pthread_join(processThread, &ret) != 0) {
perror("pthread_create() error");
exit(3);
}
delete ret; // dont forget to delete ret (avoiding of memory leak)
And use of pthread_exit() :
void * BufferedData::processData(void * arg) {
int *r = new int(10);
HelperFunctions h;
h.appendToFile("log", "test");
pthread_exit(static_cast<void*>(a));
}
General description
Allows the calling thread to wait for the ending of the target thread.
pthread_t is the data type used to uniquely identify a thread. It is returned by pthread_create() and used by the application in function calls that require a thread identifier.
status contains a pointer to the status argument passed by the ending thread as part of pthread_exit(). If the ending thread terminated with a return, status contains a pointer to the return value. If the thread was canceled, status can be set to -1.
Returned value
If successful, pthread_join() returns 0.
If unsuccessful, pthread_join() returns -1 and sets errno to one of the following values :
Error Code :
Description :
EDEADLK
A deadlock has been detected. This can occur if the target is directly or indirectly joined to the current thread.
EINVAL
The value specified by thread is not valid.
ESRCH
The value specified by thread does not refer to an undetached thread.
Notes:
When pthread_join() returns successfully, the target thread has been detached.
Multiple threads cannot use pthread_join() to wait for the same target thread to end. If a thread issues pthread_join() for a target thread after another thread has successfully issued pthread_join() for the same target thread, the second pthread_join() will be unsuccessful.
If the thread calling pthread_join() is canceled, the target thread is not detached
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 want use 5 threads on C++ program. I want create new thread when old ends working. How to implement it? How delete old threads?
Thanks!
You can use pthread_join for this purpose:
The pthread_join() function shall suspend execution of the calling
thread until the target thread terminates, unless the target thread
has already terminated. On return from a successful pthread_join()
call with a non-NULL value_ptr argument, the value passed to
pthread_exit() by the terminating thread shall be made available in
the location referenced by value_ptr. When a pthread_join() returns
successfully, the target thread has been terminated. The results of
multiple simultaneous calls to pthread_join() specifying the same
target thread are undefined. If the thread calling pthread_join() is
canceled, then the target thread shall not be detached.
You can do something of this sort,
In main, create 5 threads (detached ones possibly).
When a thread is about to terminate create a new detached thread
(and use a variable protected by a lock which indicates number of threads running
currently, if its less than 5 create thread else exit) within the
thread before exiting.
That way you will continuously create new threads.
Detached threads run detached from other threads(main included), no one waits for them to complete their execution (They don't make a thread to stop executing). Whereas, when you use pthread_join(threadName,NULL) the thread calling this function has to wait until threadName has terminated. [Both, pthread_detach and pthread_join ensure the threads resources are released]
There is nothing like deleting pthreads.
Something this way,
static int count = 5;
pthread_mutex_t mutexForCount = PTHREAD_MUTEX_INITIALIZER;
pthread_attr_t attr;
void* tFn(void* arg)
{
std::cout<<"\nI am "<<pthread_self();
pthread_mutex_lock(&mutexForCount);
count--;
if(count<=5)
{
pthread_t temp;
pthread_create(&temp,&attr,tFn,NULL);
count++;
}
pthread_mutex_unlock(&mutexForCount);
}
int main()
{
pthread_t threadArray[5];
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for(int i = 0;i<5;i++)
{
pthread_create(&threadArray[i],NULL,tFn,NULL);
}
for(int i = 0;i<5;i++)
{
pthread_join(threadArray[i],NULL);
}
pthread_exit(NULL);
}
Note: The attribute and the mutex variables should be destroyed at the end of the program. I have assumed this program runs continuosly.
The thread ends when the thread function exits.
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.
Read the problem carefully first.
There is a worker thread which gets spawned from a CreateInstance of CTest class. Here is the prototype of the class. hThread is the handle to thread and hEventShutdown is the event used to shutdown thread when program exits. WaitForShutdown is the public function which is used to signal hEventShutdown and wait on handle to thread till thread exits gracefully. WaitForShutdown is invoked from Exit of Application.
//pseudocode
CTest
{
public:
CTest* CreateInstance();
static threadproc(void *pv);
void WaitForShutdown();
public:
HANDLE hThread;
HANDLE hEventShutdown;
}
void CTest::CTest* CreateInstance()
{
// spawn a thread, pass 'this' pointer to thread , use beginthreadex
hThread = beginthreadex ( threadproc, this );
}
unsigned int CTest::threadproc( void *pv)
{
Ctest *ptest = (Ctest*)pv;
do
{
HANDLES hArray[2] = { pv->hEventShutdown, someotherhandle }
dwResult = Waitformultipleobjects( hArrary , 2);
if ( dwResult == WAIT_OBJECT_0)
delete pTest; // since it is allocated dynamically ( This is required due to some known reasons in my code)
if(dwResult == WAIT_OBJECT_0 + 1)
Doprocessing(); //DoProcessing when other thread signal someotherhandle
}while (1)
void CTest::WaitForShutdown()
{
SetEvent ( hEventShutdown);
WaitForSingleObject ( hThread,INFINITE);
}
void CTest::~CTest()
{
Closehandle(hThread)
Closehandle(hEventShutdown);
}
Now if you look at the code carefully, you will find that event is signaled from WaitForShutdown function, thread comes out of WaitForMultipleOjbects and deletes pointer of CTest. It means destructor of CTest is invoked which will obviously close thread handle ( hThread). But WaitForSingleObject from WaitForShutdown is actually waiting on thread handle. So here behavior will be undefined ( I think so, you can correct me if I am wrong). Another problem is destructor of Ctest is invoked when WaitForSingleObject is waiting on its member hThread which is not correct. I can not remove delete pTest from thread since it has to be there due to some reasons.
How will you suggest the solution to the above ?
Couple of Solution which I can think of :
I can keep thread handle in another map but I dont want to do it.
I can copy thread handle to some local variable before WaitForSingleObject in WaitForShutdown and will wait on it. Don;t know is it right ? you tell me.
Or I will use Duplicatehandle API to get reference of existing thread handle before WaitForSingleObject and wait on it. Dont know is it correct. Dont know if will the duplicate handle be alive after CloseHandle on original.
I will keep thread ID, get thread handle from thread ID and keep waiting on thread handle in WaitForShutdown. This looks more elegant but I do not know is there any way to get handle from thread id.
Correct me.
Your feedback appreciated.
The simplest way to handle this would be to simply delete the thread from WaitForShutdown, after WaitForSingleObject returns. This ensures all the handles you need - and more importantly, the object itself - remain alive to the end.
I have run this piece as is. Seems it works, and it doesn't crash.
Strangely that we can call CloseHandle(hthread), before we go out of WaitforSingleObject(hThread,INFINITE).
Of course, "academic" way to join thread is firstly WaitForSingleObject(hThread,INFINITE) than CloseHandle(hThread). So that is my suggestion - do in this way.
I don't have to add anymore.
I want to start a new thread from the main thread. I can't use join since I don't want to wait for the thread to exit and than resume execution.
Basically what I need is something like pthread_start(...), can't find it though.
Edit:
As all of the answers suggested create_thread should start thread the problem is that in the simple code below it doesn't work. The output of the program below is "main thread". It seems like the sub thread never executed. Any idea where I'm wrong?
compiled and run on Fedora 14 GCC version 4.5.1
void *thread_proc(void* x)
{
printf ("sub thread.\n");
pthread_exit(NULL);
}
int main()
{
pthread_t t1;
int res = pthread_create(&t1, NULL, thread_proc, NULL);
if (res)
{
printf ("error %d\n", res);
}
printf("main thread\n");
return 0;
}
The function to start the thread is pthread_create, not
pthread_join. You only use pthread_join when you are ready to wait,
and resynchronize, and if you detach the thread, there's no need to use
it at all. You can also join from a different thread.
Before exiting (either by calling exit or by returning from main),
you have to ensure that no other thread is running. One way (but not
the only) to do this is by joining with all of the threads you've
created.
the behaviour of your code depends on the scheduler; probably the main program exits before printf in the created thread has been executed. I hope simple sleep(some_seconds) at the end of the main() will cause the thread output to appear :)
the join call waits for the thread to terminate and exit.
if you want your main thread to continue its execution while the child thread is executing, don't call join: the child thread will execute concurrently with the main thread...
Just create the thread with the detached attribute set to on. To achieve this, you can either call pthread_detach after the thread has been created or pthread_attr_setdetachstate prior to its creation.
When a thread is detached, the parent thread does not have to wait for it and cannot fetch its return value.
you need to call pthread_exit in the end of man(), which will cause main to wait other thread to start and exit.
Or you can explicitly call pthread_join to wait the newly created thread
Otherwise, when main returns, the process is killed and all thread it create will be killed.
The thread starts automatically when you create it.
Don't you just need to call pthread_create?
static void *thread_body(void *argument) { /* ... */ }
int main(void) {
pthread_t thread;
pthread_create(&thread, NULL, thread_body, NULL);
/* ... */