passing a single integer to a multithread function in C++ - c++

I want to call a function with multiple threads, and I only need to pass a single integer to that function (the thread id, so if it is accessible I need no value to pass).
How should I do this?
for example like:
for(int i=0; i < numberOfThread; i++ ){
pthread_create(&threads[i], NULL, multichaper, &td[i]);
}
in which multichaper is my function and threadID is an integer.
Update: I marked the answer from user3286661 as the right answer and that worked for me, if you want a more detailed answer you can check my own solution to this question in answers.

General approach to this is to make the function like this:
void* multichaper(void* arg) {
int tid = *(int*)arg;
...
}
And while calling pthread_create:
pthread_create(&threads[i], NULL, multichaper, &td[i])
where td[i] is an int.

You really should consider moving to C++11 threads:
#include <thread>
#include <iostream>
void show_id(int id) {
std::cout << id << std::endl;
}
int main()
{
std::thread t(show_id, 10);
t.join();
}
If you must use pthreads, though:
#include <iostream>
#include <pthread.h>
void *show_id(void *x_void_ptr)
{
const int id = *static_cast<int *>(x_void_ptr);
std::cout << id << std::endl;
return NULL;
}
int main()
{
pthread_t t;
int id = 10;
if(pthread_create(&t, NULL, show_id, &id)) {
std::cerr << "couldn't create" << std::endl;
return -1;
}
if(pthread_join(t, NULL)) {
std::cerr << "couldn't join" << std::endl;
return -2;
}
}
Note how much better the first version is:
No casts
Fewer explicit checks
No problem with the lifetime of the object you're passing - in the first version, you're passing a pointer to it, and thus must ensure it's "alive" while the thread is using it.
No unintuitive void * returns (with the same lifetime problems).

No. You can't do that. The function you pass to pthread_create must have the signature void *(*start_routine) (void *). That is, a function taking a non-const pointer to void and returning a non-const pointer to void.
The simplest way is something like:
int *arg = new int(threadID);
pthread_create(&threads[i], NULL, multichaper, threadID );
and then multichaper looks like:
void *multichaper(void *arg)
{
int *pint = static_cast<int*>(arg);
int threadID = *pint;
delete pint;
...
return nullptr;
}
Note that I have allocated the int on the heap to avoid having to worry about variable lifetimes. If you can guarantee that the variable threadID in the calling function will outlive the thread, then you can skip that bit.
I strongly recommend you use C+11 and the built-in threading library, or if you can't do that, use boost::threads. They both make this much easier!

As i want to pass numbers from 0 to NumberOfThreads to my function i finally used the code below, by passing an integer inside a struct and locking (lock_mutex) that when trying to retrieve the threadNum:
Calling function in multi threads in a member function of SVAnchor class:
pthread_t threads[this->numberOfThread];
pthread_attr_t attr;
params_t params;
pthread_mutex_init (&params.mutex , NULL);
pthread_cond_init (&params.done, NULL);
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for(int i=0; i < this->numberOfThread; i++ ){
params.id = i;
params.ptr = this;
rc = pthread_create(&threads[i], NULL, &(SVAnchor::multichaperWrapper), &params);
pthread_cond_wait (&params.done, &params.mutex);
}
pthread_attr_destroy(&attr);
void* status;
for(int i=0; i < this->numberOfThread; i++ )
rc = pthread_join(threads[i], &status);
pthread_mutex_destroy (&params.mutex);
pthread_cond_destroy (&params.done);
with params_t as follows:
struct params {
SVAnchor* ptr;
pthread_mutex_t mutex;
pthread_cond_t done;
int id;
};
typedef struct params params_t;
and then multichaperWrapper is as follows:
void* SVAnchor::multichaperWrapper(void* arg){
return (((params*)arg)->ptr)->multichaper( ((params*)arg));
}
and multichaper is as follows:
void* SVAnchor::multichaper( void *threadarg /*0 <= threadNum < numberofthreads*/ ){
int threadNum;
/* Lock. */
pthread_mutex_lock(&(*(params_t*)(threadarg)).mutex);
/* Work. */
threadNum = (*(params_t*)(threadarg)).id;
/* Unlock and signal completion. */
pthread_mutex_unlock(&(*(params_t*)(threadarg)).mutex);
pthread_cond_signal (&(*(params_t*)(threadarg)).done);
cout<<threadNum<<endl;
...
}

If all you want to do is pass an id to the calling thread you can do so by burying it in the void* parameter, and do so portably. Like,
pthread_create(&threads[i], NULL, multichaper, (void*)threadID );

Related

Call join child pthread in main function

I have the test code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t th_worker, th_worker2;
void * worker2(void *data) {
for(int i = 0; i< 1000000; i++){
printf("thread for worker2----%d\n", i);
usleep(500);
}
}
void * worker(void *data){
pthread_create(&th_worker2, NULL, worker2, data);
for(int i = 0; i< 100; i++){
printf("thread for worker-----%d\n", i);
usleep(500);
}
}
void join(pthread_t _th){
pthread_join(_th, NULL);
}
In main() function, If I call join(the_worker2):
int main() {
char* str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void*) str);
/* problem in here */
join(th_worker2);
return 1;
}
--> Segment Fault error
Else, i call:
join(the_worker);
join(th_worker2);
---> OK
Why have segment fault error in above case?
Thanks for help !!!
If you posted all your code, you have a race condition.
main is synchronized with the start of worker but not worker2.
That is, main is trying to join th_worker2 before worker has had a chance to invoke pthread_create and set up th_worker2 with a valid [non-null] value.
So, th_worker2 will be invalid until the second pthread_create completes, but that's already too late for main. It has already fetched th_worker2, which has a NULL value and main will segfault.
When you add the join for th_worker, it works because it guarantees synchronization and no race condition.
To achieve this guarantee without the join, have main do:
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
while (! th_worker2)
usleep(100);
/* problem in here */
join(th_worker2);
return 1;
}
An even better way to do this is to add an extra variable. With this, the first loop is not needed [but I've left it in]:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int worker_running;
pthread_t th_worker;
int worker2_running;
pthread_t th_worker2;
void *
worker2(void *data)
{
// tell main we're fully functional
worker2_running = 1;
for (int i = 0; i < 1000000; i++) {
printf("thread for worker2----%d\n", i);
usleep(500);
}
return NULL;
}
void *
worker(void *data)
{
// tell main we're fully functional
worker_running = 1;
pthread_create(&th_worker2, NULL, worker2, data);
for (int i = 0; i < 100; i++) {
printf("thread for worker-----%d\n", i);
usleep(500);
}
return NULL;
}
void
join(pthread_t _th)
{
pthread_join(_th, NULL);
}
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
// NOTE: this not necessarily needed as loop below is better
while (! th_worker2)
usleep(100);
// give worker2 enough time to completely start
while (! worker2_running)
usleep(100);
/* problem in here (not anymore!) */
join(th_worker2);
return 1;
}

Why the synchronization is not happening in multithread application c++

I am new to multithreading.
When I am running the below program it is giving output as
Function1
Function2
1000...1001
but when I am debugging the program it is giving output as expected.
1000...1001
Function1
Function2
So,I think at directly running time (without debugging) mode it is getting some synchronization problem. But one thing confuses me that, I am using mutex then why synchronization problem is happening?
Please help me.
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
pthread_mutex_t myMutex;
void * function1(void * arg);
void * function2(void * arg);
void * function0(void * arg);
int count = 0;
const int COUNT_DONE = 10;
main()
{
pthread_t thread1, thread2, thread0;
pthread_mutex_init(&myMutex, 0);
pthread_create(&thread0, NULL, &function0, NULL );
pthread_create(&thread1, NULL, &function1, NULL );
pthread_create(&thread2, NULL, &function2, NULL );
pthread_join(thread0, NULL );
pthread_join(thread1, NULL );
pthread_join(thread2, NULL );
pthread_mutex_destroy(&myMutex);
return 0;
}
void *function1(void * arg)
{
cout << "Function1\n";
}
void *function0(void *arg)
{
int i, j;
pthread_mutex_lock(&myMutex);
for (i = 0; i <= 1000; i++)
{
for (j = 0; j <= 1000; j++)
{
}
}
cout << i << "..." << j << endl;
pthread_mutex_unlock(&myMutex);
}
void *function2(void * arg)
{
cout << "Function2\n";
}
"... getting some synchronization problem" where do you see a problem?
The threads output could come in any order, as the threads are not synchronised in any case.
The mutex is used only in one thread.
Also
Function1
1000...1001
Function2
might be an expectable and valid result.
As well as:
1000
Function1
...
Function2
1001
Modifying function1() and function2() like so:
void *function1(void * arg)
{
pthread_mutex_lock(&myMutex);
cout << "Function1\n";
pthread_mutex_unlock(&myMutex);
}
void *function2(void * arg)
{
pthread_mutex_lock(&myMutex);
cout << "Function2\n";
pthread_mutex_unlock(&myMutex);
}
would protect the program from producing the 2nd of my example outputs.

C++ Wait all threads to finish

#include <stdio.h>
#include <process.h>
#include <wtypes.h>
typedef unsigned int (__stdcall * THREAD_FUN_TYPE)(void *);
int ThreadIp(void* param)
{
while(true)
{
printf("I'm runing!\n");
}
return 0;
}
int main()
{
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
phThreads[i]=(HANDLE*)_beginthreadex(NULL, 0, (THREAD_FUN_TYPE)ThreadIp,NULL, NULL, NULL);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
printf("End!\n");
return 0;
}
I want the program will halt at WaitForMultipleObjects until all thread are end(Not until all thread are created successfully).But the program will not halt at WaitForMultipleObjects,while all threads are still running. So I try to use SetEvent,but still the same problem:
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
phThreads[i]=CreateEvent(NULL, FALSE, FALSE,NULL);
ResetEvent(phThreads[i]);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
You should wait on the thread handles, not the unrelated events:
Try something like this:
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
m_iCurThreadNum=i;
phThreads[i] = _beginthreadex(...);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
Does it work if you have fewer threads? The manual says you need to do extra work if you have more than MAXIMUM_WAIT_OBJECTS, specifically
nCount [in] The number of object handles in the array pointed to by
lpHandles. The maximum number of object handles is
MAXIMUM_WAIT_OBJECTS. This parameter cannot be zero.
See here for a discussion.
It might be worth checking what the wait function has returned too.
I would allocate a struct before calling _beginthreadex and pass the pointer to the struct through the threads parameter and have the struct contain a bool which is set by the thread when it's done.
struct ThreadStruct{
bool Done;
char* ParamData;
int ParamDataSize;
};
int ThreadIp(void* param)
{
ThreadStruct* ts = (ThreadStruct*)param;
while(true)
{
printf("I'm runing!\n");
}
ts->Done = true;
return 0;
}
int main()
{
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
ThreadStruct* structs = new ThreadStruct[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
ZeroMemory(structs[i], sizeof(ThreadStruct));
phThreads[i]=(HANDLE*)_beginthreadex(NULL, 0, (THREAD_FUN_TYPE)ThreadIp, structs[i], NULL, NULL);
ResetEvent(phThreads[i]);
}
for(unsigned int i=0; i<iThreadNum;){
if(!structs[i]->Done) i=0;
else i++;
}
printf("End!\n");
return 0;
}

passing a structure to a thread

I want to know how to pass a structure to a thread. I've written an example application where I declare a structure in main and try to pass it to the thread.
Here's my code:
DWORD WINAPI Name1(LPVOID lparam)
{
data x;
x.name[15]="Sarah";
x.DOB="19/10/2007";
fputs(stdout,name,15);
fputs(stdout,DOB,15);
return 0;
}
int main()
{
struct data
{
char name[15];
char DOB[15];
};
HANDLE thread2;
DWORD threadID2;
thread2= CreateThread(NULL,0,Name1,(LPVOID *)data,0,&threadID2);
if(thread2==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
return 0;
}
Unfortunately, I am not getting the hang of passing a structure to a thread :( I would really appreciate it if somebody helped me out.
I tried to change the datatype of the structure to pass it, but, I guess I don't know how to do it.
You are passing a local variable to the thread startup function. Once the variable goes out of scope it will be destroyed. This means it may not exist when the new thread tries to access it. You should either pass by value for integral types or allocate the object in dynamic storage (the heap).
Once the new thread has the pointer to the object it should probably be responsible for destroying it as well. That all depends on how you want to assign and manager ownership of the object.
struct Foo
{
char name[15];
char DOB[15];
};
void Start()
{
Foo *someObject = new Foo();
CreateThread(NULL, 0, threadFunc, (LPVOID *)someObject, 0, &threadID2);
}
DWORD WINAPI threadFunc(void *v)
{
Foo *someObject = static_cast<Foo*>(v);
delete someObject;
return 0;
}
If you want to pass a struct to a thread, you've to get that struct on the heap and not on the stack and pass its address to the thread.
I also fixed a few mistakes... Like string copy, and so on...
I didn't use any typedef, as it appears you're using C++.
struct data{
char name[15];
char DOB[15];
};
DWORD WINAPI Name1(LPVOID lparam)
{
data *x = (data*)lparam;
strcpy(x->name, "Sarah");
strcpy(x->DOB, "19/10/2007");
fputs(stdout, x->name, 15);
fputs(stdout, x->DOB, 15);
HeapFree(GetProcessHeap(), 0, x);
return 0;
}
int main()
{
HANDLE thread2;
DWORD threadID2;
data * x;
x = HeapAlloc(GetProcessHeap(), 0, sizeof(data));
thread2= CreateThread(NULL, 0, Name1, (LPVOID)x, 0, &threadID2);
if(thread2==NULL)
{
cout << "Couldn't Create Thread:(" << endl;
exit(0);
}
return 0;
}

"Un-casting" from (void *) and de-referencing to char array

I have almost completed an homework assignment where I am required to use pthreads. I have figured out the pthreads. The only problem I have left is figuring out how to pass multiple arguments to threads through pthread_create().
I need to pass two chars to the thread. I have to cast them to (*void) to use with pthread_create(). I can pass them, but I can't figure out how to get the values from *parameter in the function.
void *my_function(void *parameter) {
/* ATTEMPT 1 - DOESN'T WORK */
//char* arguments[2];
//arguments = (char * [2]) parameter;
/*Error message:
error: ISO C++ forbids casting to an array type char* [2] [-fpermissive]
error: incompatible types in assignment of char** to char*[2]
*/
/* ATTEMPT 2 - DOESN'T WORK */
//char *my_data = (char *)parameter;
//my_data is blank when I try to use cout to check it's values
/* What I need to do is get those two chars from the array and print them out as part of this thread function */
pthread_exit(NULL);
}
int main(int argc, char **argv) {
char duration = '5'; //in reality, this value is taken from argv but I am leaving that out for brevity
pthread_t threads[3];
for(int i=0; i < 3; i++){
char thread_args[2] = {i, duration};
//create thread with arguments passed in
int results = pthread_create(&threads[i], NULL, my_function, (void *) &thread_args);
//testing for pthread error
if (results){
printf("ERROR; return code from pthread_create() is %d\n", results);
exit(-1);
}
}
/* Wait for all threads to complete */
for (int j=0; j < num_threads; j++) { // https://computing.llnl.gov/tutorials/pthreads/
pthread_join(threads[j], NULL);
}
/* some information prints here that is unrelated to my problem (the date, time, etc) */
pthread_exit(NULL);
}
I was able to pass one value through with no problem. Any suggestions?
The closest existing question I could find was this but I still am having no luck: Converting from void* to char ** in C
Thank you!
Note that within this loop:
for(int i=0; i < 3; i++){
char thread_args[2] = {i, duration};
int results = pthread_create(&threads[i], NULL, my_function, (void *)
...
}
thread_args is a local array with automatic storage duration, lifetime of which is tied to each iteration so there is a chance that the memory where you store these arguments might be freed before the thread will access it, which would lead to undefined behavior in that case.
Much better approach would be to create a structure, that you would use to pass the data to this thread:
typedef struct {
char duration;
int num;
} ThreadData;
Then your code could look like this:
void *my_function(void *parameter) {
// retrieve and print the thread data:
ThreadData* td = (ThreadData*) parameter;
printf("num = %d, duration = %c\n", td->num, td->duration);
delete td;
return NULL;
}
int main(int argc, char **argv) {
char duration = '5';
pthread_t threads[3];
for (int i = 0; i < 3; i++) {
// create structure that will be passed to thread:
ThreadData* td = new ThreadData;
td->duration = duration;
td->num = i;
//create thread with arguments passed in:
int ret = pthread_create(&threads[i], NULL, my_function, (void *) td);
//testing for pthread error:
if (ret) {
printf("ERROR; return code from pthread_create() is %d\n", ret);
exit(-1);
}
}
// wait for all threads to complete:
for (int i = 0; i < 3; i++) {
pthread_join(threads[i], NULL);
}
exit(0);
}
Also note that to end thread's execution it is better to use return than pthread_exit since with return it is guaranteed that variables within thread's routine will be destroyed and stack will be unwound. For more information see return() versus pthread_exit() in pthread start functions