How do i properly call a function while creating pthread? - c

I am creating a pthread in the main function and calling another function called "PrintHello". the "PrintHello" function should print some messages. My threads are being created but i am guessing my function "PrintHello" isn't being called properly as the messages are not printing.
I have put another print command in "PrintHello" function and that is printing. That means the function is being called. but i can't figure out why the messages aren't printing.
char *messages[NUM_THREADS];
struct thread_data
{
int thread_id;
int sum;
char *message;
};
struct thread_data thread_data_array[NUM_THREADS];
void *PrintHello(void *threadarg)
{
printf("I am in PrintHello");
int taskid , sum;
char *hello_msg;
struct thread_data *my_data;
Sleep(1);
my_data = (struct thread_data *) threadarg;
taskid = my_data ->thread_id;
sum = my_data ->sum;
hello_msg = my_data ->message;
printf("Thread %d: %s Sum=%d\n", taskid , hello_msg , sum) ;
pthread_exit(NULL);
}
int main(int argc , char *argv[])
{
pthread_t threads[NUM_THREADS];
int *taskids[NUM_THREADS];
int rc, t, sum;
sum=0;
messages[0] = "English: Hello World!";
..............
messages[7] = "Latin: Orbis , te saluto!";
for(t=0;t<NUM_THREADS;t++)
{
sum = sum + t;
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
thread_data_array[t].message = messages[t];
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL , PrintHello , (void *) &thread_data_array[t]);
//rc = pthread_create(&threads[t], NULL , PrintHello , NULL);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d \n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
The code should print out the hello messages.

I assume what's happening is your application is exiting before your threads have the chance to actually execute fully. Since you are storing each thread handle in the array of pthread_t threads[NUM_THREADS]; what you will need to do is upon creation a call to
pthread_join should be made which will allow the caller thread to be blocked until the thread has executed and returned. You can call pthread_join right after you call pthread_create or loop through all your handles and call pthread_join on each index in your array. If a call to pthread_join is made after the creation of each thread individually then a new thread will not spawn until the previous finishes. If you wish to execute them simultaneously then a loop after all the threads have been created would be the better option.
int main(int argc , char *argv[])
{
pthread_t threads[NUM_THREADS];
int *taskids[NUM_THREADS];
int rc, t, sum;
sum=0;
messages[0] = "English: Hello World!";
..............
messages[7] = "Latin: Orbis , te saluto!";
for(t=0;t<NUM_THREADS;t++)
{
sum = sum + t;
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
thread_data_array[t].message = messages[t];
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL , PrintHello , (void *) &thread_data_array[t]);
//rc = pthread_create(&threads[t], NULL , PrintHello , NULL);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d \n", rc);
exit(-1);
}
}
for(int index = 0; index < NUM_THREADS; ++index){
pthread_join(threads[index],NULL);//Wait for execution of each thread
}
}
You also don't need to call pthread_exit in your main. Typically that should be called in the thread you wish to terminate early where the value passed into pthread_exit can be retrieved from the second argument of pthread_join

Sorry for the late reply. I should have mentioned that i am using Windows. Anyway, i found out the problem. It is happening because of the "sleep" argument. For windows apparently it is different. so i changed my sleep argument to Sleep(1000), which apparently means 1 second in windows and that solved my problem. Thank you for all the replies.

Related

Multi threading using p thread Linux problem

I have two functions, producer and consumer called by two p threads, but the while loop in the function is not running. Its a linux RT system. this is my code. im coding in eclipse.
#include <stdio.h>
#include"NIDAQmx.h"
#include <pthread.h>
#include "sts_queue/s_q.c"
#include <stdlib.h>
void *producer(void *ptr);// first function
void *consumer(void *ptr);// second function
TaskHandle taskHandle = 0;
int ret = 0;
int numChannels = 0;
int numRead;
float64 data[100];
int iret1, iret2;
pthread_t thread1, thread2;
int main(void) {
char *message1 = "Producer ended";
char *message2 = "consumer ended";
init();
ret = DAQmxCreateTask("task", &taskHandle);
ret=DAQmxCreateAIVoltageChan(taskHandle, "PXI1Slot2/ai0", "",
DAQmx_Val_Cfg_Default, -5, 5, DAQmx_Val_Volts, NULL);
ret=DAQmxCfgSampClkTiming(taskHandle, "", 1000, DAQmx_Val_Rising,DAQmx_Val_ContSamps, 100);
ret=DAQmxGetTaskAttribute(taskHandle, DAQmx_Task_NumChans, &numChannels);
ret=DAQmxStartTask(taskHandle);
iret1 = pthread_create(&thread1, NULL, producer,(void*) message1);// calling two threads
iret2 = pthread_create(&thread2, NULL, consumer,(void*) message2);// calling thread
}
void *producer(void *ptr) // enque function
{
char *message;
int i = 0;
int ret;
message = (char *) ptr;
while(i<1000)
{
//ret=DAQmxReadAnalogF64(taskHandle, 100, 10.0, DAQmx_Val_GroupByChannel, data,100 * numChannels, &numRead, NULL);
printf("task handle=%d\n",taskHandle);
printf("value of i=%d\n",i);
printf("Number of sample read%d\n",numRead);
printf("ret%d\n",ret);
sleep(.1);
i++;
}
ret=DAQmxStopTask(taskHandle);
ret=DAQmxClearTask(taskHandle);
printf("%s \n", message);
pthread_join(thread1, NULL);
return 0;
}
void *consumer(void *ptr) // deque function
{
char *message;
int k = 0;
int elements=0;
message = (char *) ptr;
while(k<1000)
{
printf("value ofk=%d\n",k);
sleep(.1);
k++;
}
printf("%s \n", message);
pthread_join(thread2, NULL);
}
Should i use pthread_exit or pthread-join?
how to use pthead_exit to exit first thread when while loop has exited?
now my console prints just this
task handle=-163491360
start0
value ofk=0
task handle=-163491360
value of i=0
Number of sample read0
ret0
logout
but actually value of i and k should go to 1000 and when it reaches 1000, while loop will stop and exit
Sometimes im getting this error too
pure virtual method called
terminate called without an active exception
Aborted
logout
You need to call pthread_join in the main function after creating thread1 and thread2. Otherwise, the main thread will terminate before thread1 and thread2 are completed.

pthread_detach doesn't change anything

I understand pthread_detach(pid) that: "storage for the thread thread can be reclaimed when that thread terminate" (as per http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_detach.html)
However, I understand that means that once the pid thread finishes executing, its memory will be freed, and we will not be able to run it again, or call join on it.
However, I tried the following code:
#include <stdio.h>
#include <pthread.h>
void* myFunction (void* arg)
{
printf("Hello World from thread!\n");
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, myFunction, NULL);
//pthread_join(tid, NULL);
int isDetached = -10;
isDetached = pthread_detach(tid);
printf("Is my thread detached: %d\n", isDetached);
int i;
for (i = 0; i<15; i++)
printf("%d\n", i);
pthread_create(&tid, NULL, myFunction, NULL);
pthread_join(tid, NULL);
for (i = 0; i<15; i++)
printf("%d\n", i);
return 0;
}
And I get the following:
If I understand correctly, since I did pthread_detach(tid), I should not be able to be able to do
pthread_create(&tid, NULL, myFunction, NULL);
pthread_join(tid, NULL);
after it, yet I did and it works perfectly. So, what is really the purpose of doing othread_detach(pid) if we can still run the thread and join it?
Thanks a lot!
pthread_detach simply tells your program that the current instance of tid will not join, (pthread_join) again, and frees up any pthread handles & objects on the tid instance.
Since you called pthread_detach if you try to pthread_join that thread it will not since it has been released and disposed of.
I've added the pthread_join to your code right after the detach call and you can see nothing happens as expected.
#include <stdio.h>
#include <pthread.h>
void * myFunction (void *arg)
{
printf ("Hello World from thread!\n");
}
int main ()
{
pthread_t tid;
pthread_create (&tid, NULL, myFunction, NULL);
//pthread_join(tid, NULL);
int isDetached = -10;
isDetached = pthread_detach (tid);
printf ("Is my thread detached: %d\n", isDetached);
/* ADDED FOR STACK OVERFLOW */
pthread_join (tid, NULL);
int i;
for (i = 0; i < 15; i++)
printf ("%d\n", i);
pthread_create (&tid, NULL, myFunction, NULL);
pthread_join (tid, NULL);
for (i = 0; i < 15; i++)
printf ("%d\n", i);
return 0;
}
I'm not sure what the confusion is but if you were expecting a different behavior when you called pthread_create a second time; note, this is really creating a fresh instance of tid for you. Therefore your second join call runs the thread.
pthread_t tid;
pthread_create(&tid, NULL, myFunction, NULL);
This creates a new thread and subsequent call topthread_detach(pid) detaches the thread created. Now
pthread_create(&tid, NULL, myFunction, NULL);
This creates a new thread and subsequently you have called a join which basically waits for the completion of the newly created thread, not for the one which has been detached.
You can check the code attached below. When you run this code the thread which has been detached is printing even after join is called i.e myfunc1 is still printing after the pthread_join.
#include <stdio.h>
#include <pthread.h>
void *myFunction2 (void *arg)
{
printf("Hello World from func2!\n");
}
void *myFunction1 (void *arg)
{
while(1) {
printf("Hello World from func1\n");
}
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, myFunction1, NULL);
//pthread_join(tid, NULL);
int isDetached = -10;
isDetached = pthread_detach(tid);
printf("Is my thread detached: %d\n", isDetached);
int i;
pthread_create(&tid, NULL, myFunction2, NULL);
pthread_join(tid, NULL);
for (i = 0; i<15; i++)
printf("%d\n", i);
return 0;
}
Your variable, tid, is not a thread. Your program does not start one thread two times, it creates two completely different threads.
The actual threads are objects that exist in the operating system. Your tid variable is just a "handle" that you can use to interact with a thread. Your second call to pthread_create(&tid,...) is re-using the handle variable, pointing it to a new, different thread.

In C, how do I pass variables to functions in Pthreads upon thread creation?

Working from this example:
https://computing.llnl.gov/tutorials/pthreads/samples/hello.c
I've worked backwards and tried to edit in what I'm hoping to accomplish.
I'd like to pass data to the thread being spawned.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long NUM_THREADS=0;
void *Entropy(void *depth)
{
long tid;
tid = (long)depth;
printf("This is where things get done.\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
printf("Cores: %i\n", NUM_THREADS);
pthread_t threads[NUM_THREADS];
int rc;
long t;
int depth;
depth = atoi(argv[1]);
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
I see on line:
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
My function Entropy gets called here, so I thought I'd try to tack on some brackets and pass a variable to that function the way I'd seen it done before. This seems to be a little different though, since this whole line returns something to rc, I wonder if that changes how I pass data to my thread, but I'm not sure how else I'd do it.
Right now this code compiles and runs, int main() goes fine without a hitch but it seg faults the moment it tries to create new threads.
In order to pass data to a thread you need to prepare the data in some place in memory, and pass a pointer to that place into pthread_create. It is pthread_create's job to pass that pointer to the runner function of your thread:
typedef struct {
long tid;
int depth;
}thread_data;
...
void *Entropy(void *dataPtr) {
thread_data *data= (thread_data*)dataPtr;
printf("This is where things get done for %li.\n", data->tid);
pthread_exit(NULL);
}
...
pthread_t threads[NUM_THREADS];
thread_data data[NUM_THREADS];
...
for(t=0;t<NUM_THREADS;t++) {
data[t].tid = t;
data[t].depth = depth;
rc = pthread_create(&threads[t], NULL, Entropy, (void *)&data[t]);
}
Your code crashes since you pass incorrect parameters:
rc = pthread_create(&threads[t], NULL, Entropy(depth), (void *)t);
// ^^^^^^^^^^^^^^
Here you should pass function pointer void *(*)(void *) but you are passing void *, and moreover value is unspecified since Entropy() has no return statement (did you turn warnings on at all?). I guess it should be like this:
rc = pthread_create(&threads[t], NULL, Entropy, (void *)t);
Next, how to pass parameter to thread routine? Technically you can use any pointer, but you should think twice about what you are passing. First of all pointed data must be valid when new thread runs. I.e. you shouldn't pass addresses of any locals except if you are sure that thread is finished when you are leaving scope of passed data - use pthread_join(new_thread) at the scope end to achieve that. Another approach is to pass pointer to data at global scope, that is surely valid at any moment. But there is one flaw - such data are visible to all threads, so you may accidentally make a mess. To avoid it - use dynamic memory - allocate data block with malloc() pass pointer to thread and free it in that thread. Latter option reduces chances to corrupt someone's else data.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
long NUM_THREADS=0;
void *Entropy(void *depth)
{
long tid = *((long *)depth);
free(depth);
printf("This is where things get done.\n", tid);
return NULL;
}
int main(int argc, char *argv[])
{
NUM_THREADS = sysconf(_SC_NPROCESSORS_ONLN);
printf("Cores: %i\n", NUM_THREADS);
pthread_t threads[NUM_THREADS];
int rc;
long t;
int depth;
depth = atoi(argv[1]);
for(t=0;t<NUM_THREADS;t++){
long *arg = malloc(sizeof(*arg));
*arg = t;
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, Entropy, arg);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for(t=0;t<NUM_THREADS;t++){
pthread_join(threads[t], NULL);
}
}

Is pthread_join a must when using pthread in linux?

I an learning pthread and I have a few questions.
Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define NUM_THREADS 10
using namespace std;
void *PrintHello(void *threadid)
{
int* tid;
tid = (int*)threadid;
for(int i = 0; i < 5; i++){
printf("Hello, World (thread %d)\n", *tid);
}
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
int t;
int* valPt[NUM_THREADS];
for(t=0; t < NUM_THREADS; t++){
printf("In main: creating thread %d\n", t);
valPt[t] = new int();
*valPt[t] = t;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)valPt[t]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
The code runs well and I don't call pthread_join. So I want to know, is pthread_join a must?
Another issue, is:
valPt[t] = new int();
*valPt[t] = t;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)valPt[t]);
equal to:
rc = pthread_create(&threads[t], NULL, PrintHello, &i);
It is not. But you need either pthread_exit() or pthread_join().
Here you called pthread_exit(), thats why the child threads continue execution even after the main thread terminates.
If there is any need for the main thread to wait till the child threads complete execution, you can use pthread_join().

Dynamically allocating struct inside a loop

I have wrote a simple program to play with pthreads .
Each thread receives as thread data a pointer to a struct and prints it. Then I have wrote a loop to dynamically allocate structs and then use the point in the thread creation.
The problem is, Why does all threads receive the same stuct although I have allocated different loops?
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
struct thread_data {
long thread_id;
int thread_sum;
};
void *PrintHello(void *threadData)
{
struct thread_data *data_input = (struct thread_data *)threadData;
printf("Hello World! It's me, thread #%ld! ,%d , pointer %d\n", data_input->thread_id, data_input->thread_sum, data_input);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];;
struct thread_data allData[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++){
struct thread_data* data = malloc(sizeof(struct thread_data));
//allData[t].thread_id = t;
//allData[t].thread_sum = 100;
// struct thread_data data;
data->thread_id = t;
data->thread_sum = 0;
printf("In main: creating thread %ld , %d , %d\n", data->thread_id, data->thread_sum, &data);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&data);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
return 0;
}
on your code &data is of type struct thread_data **
replace this
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&data);
by this
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)data);
also, you have to call free for each allocated memory inside (and just before pthread_exit) the PrintHello function
Directly use data
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
struct thread_data {
long thread_id;
int thread_sum;
};
void *PrintHello(void *threadData)
{
struct thread_data *data_input = (struct thread_data *)threadData;
printf("Hello World! It's me, thread #%ld! ,%d , pointer %d\n", data_input->thread_id, data_input->thread_sum, data_input);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];;
struct thread_data allData[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++){
struct thread_data* data = malloc(sizeof(struct thread_data));
//allData[t].thread_id = t;
//allData[t].thread_sum = 100;
// struct thread_data data;
data->thread_id = t;
data->thread_sum = 0;
printf("In main: creating thread %ld , %d , %d\n", data->thread_id, data->thread_sum, &data);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)data);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
return 0;
}
Will ouput:
In main: creating thread 0 , 0 , -273609272
In main: creating thread 1 , 0 , -273609272
Hello World! It's me, thread #0! ,0 , pointer 13357072
In main: creating thread 2 , 0 , -273609272
In main: creating thread 3 , 0 , -273609272
In main: creating thread 4 , 0 , -273609272
Hello World! It's me, thread #2! ,0 , pointer 13357712
Hello World! It's me, thread #1! ,0 , pointer 13357392
Hello World! It's me, thread #4! ,0 , pointer 13359632
Hello World! It's me, thread #3! ,0 , pointer 13358032

Resources