return argument (struct) from a thread - c

I have a function task1 that is called by the pthread_create in the main (pure C). It works but, whatever I do on my_pair is lost after the thread is over. I mean I would like the created thread task1 do operations and save them on eventT.. is it possible to return my_pair? how?
void task1(void* eventT){
//struct eventStruct *my_pair = (struct eventStruct*)eventT;
// Tried with malloc but same wrong behavior
struct eventStruct *my_pair = malloc(sizeof((struct eventStruct*)eventT));
// do stuff
my_pair->text = TRIAL;
pthread_exit( my_pair );
}
// Global variable
struct eventStruct *eventT = NULL;
//Calling the thread from the main
eventT = (struct eventStruct*)
thpool_add_work(thpool, (void*)task1, (void*) &eventT);
// Expecting eventT changed (not happening..)
pthread_join( thread, &eventT );

Here's an example of one way to return a struct from a thread - by passing in an allocted struct for the thread to return. This example is similar to your posted code, but uses only pthread functions since I don't know anything about the thpool_add_work() API.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct eventStruct
{
char const* text;
char const* more_text;
};
#define TRIAL "this is a test"
void* task1(void* eventT)
{
struct eventStruct *my_pair = (struct eventStruct*)eventT;
// do stuff
my_pair->text = TRIAL;
pthread_exit( my_pair );
}
int main(void)
{
pthread_t thread;
struct eventStruct* thread_arg = malloc(sizeof *thread_arg);
thread_arg->text = "text initialized";
thread_arg->more_text = "more_text_initialized";
//Calling the thread from the main
pthread_create( &thread, NULL, task1, thread_arg);
void* thread_result;
pthread_join( thread, &thread_result);
struct eventStruct* eventT = thread_result;
puts(eventT->text);
puts(eventT->more_text);
free(eventT);
return 0;
}
Another way this could be done is by having the returned structure allocated by the thread instead of by the caller and passing it in. I'm sure there are many other mechanisms that can be used, but this should get you started.

Related

Running thread simultaneously with program in C

I would like to run my thread simultaneously as my main program. How do I do so? Currently the thread is running a never ending loop, but i would like it to run at the same time as when my main program continues running. Here is my code.
This is my thread:
void *LEDReadingsTimer(char *buffer, int clientSocket) //void *arg
{
while(timer!=0)
{
delay(2000);
LEDReadings(buffer, clientSocket);
printf("Data Sent to Android!\n");
}
return 0;
}
Here is my main code:
timer=1;
wiringPiSetupSys () ;
gertboardAnalogSetup (100) ;
pthread_create(&tid, NULL, LEDReadingsTimer(buffer,clientSocket), NULL);
//Receive and send data from and to Android
while(1){
nread = recv(clientSocket,buffer,4096,0);//recvfrom(clientSocket, buffer,1024, 0, (struct sockaddr *) &serverStorage, &addr_size);
buffer[nread] = '\0';
if((atof(buffer)>=0)&&(atof(buffer)<=1)){
printf("Data Received: %s\n", buffer);
LEDBrightness(buffer);
//LEDReadings(buffer, clientSocket);
}
This is my LEDReadings function.
int LEDReadings(char *buffer, int clientSocket){
int x1, x2 ;
double v1, v2 ;
double a;
printf ("| Channel 0 | Channel 1 |\n") ;
// Read the 2 channels:
x1 = analogRead (100) ; //voltage
x2 = analogRead (101) ; //current
// Convert to a voltage:
v1 = (double)x1 / 1023.0 * 3.3 ;
v2 = (double)x2 / 1023.0 * 3.3 ;
a = v2*30;
printf ("%6.3f|%6.3f\n", v1, a) ;
fflush (stdout) ;
snprintf(buffer, 4096,"%6.3fsplit%6.3f\n", v1, a);
send(clientSocket,buffer,strlen(buffer)+1,0);
return 0;
}
Once my pthread runs, it doesn't go into the next while loop to do recv function.
I assume you know you have to pass pthread_create() a function pointer. There's no such thing in C as a "function pointer with arguments", it's just the address of the function. So what you do here is just call a function the normal way, this function never returns, so the pthread_create() is never executed, waiting for evaluation of one of its arguments.
Have a look at the prototype of pthread_create():
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
This means your start_routine must accept and return void *. So you have to change the signature of your function to
void *LEDReadingsTimer(void *args);
Now, how do you pass the parameters? Simply use a struct. Define this struct somewhere:
struct LEDReadingsTimerArgs
{
char *buffer;
int clientSocket;
};
Then you can change your thread function to this:
void *LEDReadingsTimer(void *args)
{
struct LEDReadingsTimerArgs *lrtArgs = args;
while(timer!=0)
{
delay(2000);
LEDReadings(lrtArgs->buffer, lrtArgs->clientSocket);
printf("Data Sent to Android!\n");
}
return 0;
}
The last argument of pthread_create is for passing the arguments, so start your thread like this:
struct LEDReadingsTimerArgs lrtArgs = {buffer, clientSocket};
pthread_create(&tid, NULL, LEDReadingsTimer, &lrtArgs);
You are calling the thread function yourself rather than giving it to pthread_create as a pointer. This means the function will run forever and no thread will ever be created.
You need to create a way to pass parameters, for example a struct
struct params
{
char *buffer;
int clientSocket;
}
Then you change your thread function into one that gets it as a parameter
void *LEDReadingsTimer(void *args)
{
struct params *pars = args;
while(timer!=0)
{
delay(2000);
LEDReadings(pars->buffer, pars->clientSocket);
printf("Data Sent to Android!\n");
}
return 0;
}
And in your main function you define a struct, set values and pass it to the thread funtion through pthread_create;
struct params pars;
pars.buffer = buffer;
pars.clientSocket = clientSocket;
pthread_create(&tid, NULL, LEDReadingsTimer, &pars);
This way your thread function is called by pthread and the parameters you pass to it will be usable from the thread. Of course always make sure the parameter struct doesn't go out of scope and get freed while the thread is running.

Incorrect output of code after using pthreads

I am working in some code trying to make it use threads, with little success. The code is as follows (using some online tuts)
(1) Create an array to save arguments to pass to each thread.
(2) The struct where thread args are stored
(3) Function each thread executes
(4) Main, where I create each pthread and pass args. end and begin are dummy i and i+1 just for testing purposes.
#include <pthread.h>
struct thread_data* thread_data_array;
struct thread_data{
int thread_id;
int begin;
int end;
};
void *proccessData(void *threadarg)
{
struct thread_data *my_data = (struct thread_data *) threadarg;
int id = my_data->thread_id;
int start = my_data->begin;
int end = my_data->end;
printf("%s%d%s%d%s%d%s","Process: Id ",id," begin: ",start," end: ",end,"\n");
// Init
FILE* fileOut;
// do stuff
fileOut = fopen(someNameUsingId, "w");
// more stuff
fclose(fileOut);
}
int main(int argc, char **argv)
{
int n_th = atoi(argv[1]);
thread_data_array = malloc(n_th*sizeof(struct thread_data));
pthread_t threads[n_th];
int i;
for (i=0; i<n_th; i++)
{
thread_data_array[i].thread_id = i;
thread_data_array[i].begin = i;
thread_data_array[i].end = i+1;
pthread_create(&threads[i], NULL, proccessData,(void *) &thread_data_array[i]);
}
}
What I am getting: Sometimes nothing is printed, Sometimes some ids are printed twice. Files are not created (one in every 5 lets say, files are created, and are empty)
But using this in main works as I am expecting, id 1 from 0 to 1 is printed, id 2 from 1 to 2, and both files are created and have the right content
thread_data_array[0].thread_id = 1;
thread_data_array[0].begin = 0;
thread_data_array[0].end = 1;
proccessData((void *) &thread_data_array[0]);
thread_data_array[1].thread_id = 2;
thread_data_array[1].begin = 1;
thread_data_array[1].end = 2;
proccessData((void *) &thread_data_array[1]);
Can someone point out what am I doing wrong, and how to solve it?
Thanks in advance
Your main is terminating before the other threads. main is special, as returning from it is equivalent to call exit.
Either use pthread_exit to end main or use pthread_join to wait for the termination of the other threads.
pthread_join will solve the issue, call it for each created thread in main. pthread_join() function is called to wait for the threads to complete. If main is done before threads are done, they will die before they finished their job.

Stopping pthread as soon as struct is freed in C

I have a worker thread processing a queue of work items. I just implemented a second worker that process the items which were inserted in worker1. However, I came across some Invalid reads while using Valgrind.
I'm assuming this is because struct foo that I pass to worker2() is freed at some point in the main thread. Essentially struct foo is a struct that constantly gets updated (malloc/free), however, I'd like worker2 to insert some missing items into foo.
My question is: is it possible for worker2 to stop processing as soon as struct foo is NULL? and start again when create_foo() is called? I'm not sure what would be the best approach to insert the missing items into foo with a thread? Any feedback is appreciated.
//canonical form
//producer
void push_into_queue(char *item)
{
pthread_mutex_lock(&queueMutex);
if (workQueue.full) { // full }
else
{
add_item_into_queue(item);
pthread_cond_signal(&queueSignalPush);
}
pthread_mutex_unlock(&queueMutex);
}
}
// consumer1
void *worker1(void *arg)
{
while (true) {
pthread_mutex_lock(&queueMutex);
while (workQueue.empty)
pthread_cond_wait(&queueSignalPush, &queueMutex);
item = workQueue.front; // pop from queue
add_item_into_list(item);
pthread_cond_broadcast(&queueSignalPop);
pthread_mutex_unlock(&queueMutex);
}
return NULL;
}
pthread_create(&thread1, NULL, (void *) &worker, NULL);
// consumer2
void *worker2(void *arg)
{
my_struct *foo = (my_struct *) arg;
while (true) {
pthread_mutex_lock(&queueMutex);
while (list.empty)
pthread_cond_wait(&queueSignalPop, &queueMutex);
for (i = 0; i < list.size; i++)
insert_item_into_foo(list[i].item, foo);
pthread_cond_broadcast(&queueSignalPop);
pthread_mutex_unlock(&queueMutex);
}
return NULL;
}
void create_foo()
{
my_struct *foo = calloc(10, sizeof(my_struct));
pthread_create(&thread2, NULL, (void *) &worker2, foo);
}
void free_foo()
{
pthread_mutex_lock(&queueMutex);
int i;
for (i=0; i<5; i++)
free(foo[i].list->string);
free(foo[i].list);
free(foo);
pthread_mutex_unlock(&queueMutex);
}
You did not define any terminating condition for both worker1 and worker2. I suppose that the eol of foo could be considered as such. This means that both workers must monitor the existence of foo by owning a reference to it (ie. a foo **).
void *worker2(void *arg)
{
my_struct **foo = (my_struct **) arg;
while(true) {
pthread_mutex_lock(&queueMutex);
while (list.empty)
pthread_cond_wait(&queueSignalPop, &queueMutex);
if (NULL == *foo)
break;
for (i = 0; i < list.size; i++)
insert_item_into_foo(list[i].item, *foo);
pthread_cond_broadcast(&queueSignalPop);
pthread_mutex_unlock(&queueMutex);
}
free(foo);
return NULL;
}
void create_foo()
{
my_struct *foo = calloc(10, sizeof(my_struct ));
my_struct **foo_ptr = malloc(1, sizeof(my_struct *));
*foo_ptr = foo;
pthread_create(&thread2, NULL, (void *) &worker2, foo_ptr);
// more work with foo
}
Note that somehow foo must be assigned to a different variable so as to be reachable in free_foo (your code supposes this fact without explicitely showing it - hence my comment at the end of create_foo).
With the code above, each instance of worker2 owns a pointer to rely on for its whole lifetime, and which it must take care of before exiting.
Update:
Perhaps a better solution consists in passing a struct to thread2, which contains the foo pointer, as well as a flag indicating if that pointer is still valid. You may add any other piece of information needed by the thread in the struct ad lib.
struct th2_data {
enum {RUNNING, TERMINATING} state;
my_struct *foo;
};
Then allocate a instance of that struct, initialize it as {RUNNING, foo}, and pass it to thread2. Keep a copy of its address somewhere to be able to signal the TERMINATING state to thread2. Indeed, as you asked in your comments, you would have to replace the if (NULL == *foo) test in thread2 by if (foo.state == TERMINATING).
Make foo global and add some pointer check in the loop.
Next time when you call create_foo, it will restart the thread.
my_struct *foo = NULL;
// consumer2
void *worker2(void *arg)
{
while (true) {
if ( fool == NULL )
return;
pthread_mutex_lock(&queueMutex);
while (list.empty)
pthread_cond_wait(&queueSignalPop, &queueMutex);
for (i = 0; i < list.size; i++)
insert_item_into_foo(list[i].item, foo);
pthread_cond_broadcast(&queueSignalPop);
pthread_mutex_unlock(&queueMutex);
}
return NULL;
}

Concurrency with pthreads, a typical misbehaviour

I'm not sure whats wrong with the program below, but it doesn't print each and every language once, but randomly some more often, some more less and some wont print
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
char *messages[] = {
"English: Hello World!",
"French: Bonjour, le monde!",
"Spanish: Hola al mundo",
"Klingon: Nuq neH!",
"German: Guten Tag, Welt!",
"Russian: Zdravstvytye, mir!",
"Japan: Sekai e konnichiwa!",
"Latin: Orbis, te saluto!"
};
#define NUM_MESSAGES (sizeof( messages ) / sizeof( char* ))
void *PrintHello( void *messageid )
{
pthread_t taskid;
int *id_ptr, message_num;
taskid = pthread_self();
printf( "This is thread with ID %lu.\n", taskid );
message_num = *((int *) messageid);
printf( "%s \n", messages[message_num] );
pthread_exit( NULL );
}
int main( int argc, char *argv[] )
{
pthread_t threads[NUM_MESSAGES];
int rc, i;
for( i = 0; i < NUM_MESSAGES; i++ ) {
void * argument = (void*) &i;
rc = pthread_create( &threads[i], NULL, PrintHello, argument );
if( rc ) {
printf( "ERROR; return code from pthread_create() is %d\n", rc );
exit( -1 );
}
}
for( i = 0; i < NUM_MESSAGES; i++ ) {
pthread_join( threads[i], NULL );
}
pthread_exit( NULL );
}
I guess the problem is somehow connected with the argument pointer. I tried to lock different parts but with no success.
You're passing the address of the variable i, which the main thread keeps changing. So you're at the mercy of scheduling: will anyone change i before your thread has a chance to run ?
Instead, you could try directly passing the string, greatly simplifying the code:
rc = pthread_create( &threads[i], NULL, PrintHello, messages[i]);
void *PrintHello(void *arg)
{
char *msg = arg;
printf("%s\n", msg);
return NULL;
}
There's another, poorer alternative where you pass the actual value of i as the argument (not its address).
This is a typical race condition.
To be exact, after a new thread is created, the executing order of the threads determines the program outcome. There are two situations:
When the thread function PrintHello is executed before the next increments i++ and the assignment void * argument = (void*) &i; in main thread, it outputs what you expect.
When the new thread PrintHello has been created but does not get scheduled until the next i++ executed in main thread. In this situation, your reference of argument in the thread function, namely message_num = *((int *) messageid); is not what you expect.
A solution for this is to dynamically allocate (using malloc)argument, and free them in the thread function after using it.
One way to pass scalar integer arguments to thread functions is to (ab-)use the following text from §6.3.2.3 of the C99 standard:
(5) An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.
Except for the last part of the second sentence, the following code should work on most systems:
int int_val;
...
pthread_create(..., ..., thread_func, (void *)int_val);
and then in thread_func cast it back to integer:
void *thread_func (void *data)
{
int int_arg = (int)data;
...
}

Passing Data to Multi Threads

I study this code from some book:
#include <pthread.h>
#include <stdio.h>
/* Parameters to print_function. */
struct char_print_parms {
/* The character to print. */
char character;
/* The number of times to print it. */
int count;
};
/* Prints a number of characters to stderr, as given by PARAMETERS,
which is a pointer to a struct char_print_parms. */
void* char_print(void* parameters) {
/* Cast the cookie pointer to the right type. */
struct char_print_parms* p = (struct char_print_parms*) parameters;
int i;
for (i = 0; i < p->count; ++i)
fputc(p->character, stderr);
return NULL;
}
/* The main program. */
int main() {
pthread_t thread1_id;
pthread_t thread2_id;
struct char_print_parms thread1_args;
struct char_print_parms thread2_args;
/* Create a new thread to print 30,000 ’x’s. */
thread1_args.character = 'x';
thread1_args.count = 30000;
pthread_create(&thread1_id, NULL, &char_print, &thread1_args);
/* Create a new thread to print 20,000 o’s. */
thread2_args.character = 'o';
thread2_args.count = 20000;
pthread_create(&thread2_id, NULL, &char_print, &thread2_args);
usleep(20);
return 0;
}
after running this code, I see different result each time. and some time corrupted result. what is wrong and what the correct way to do that?
Add:
pthread_join( thread1_id, NULL);
pthread_join( thread2_id, NULL);
to the bottom of your code, before the return in main. Your prosess ends before your threads can complete. A sleep of 20 micro seconds is not enough to let your threads complete executing. Safer to wait for the threads to return.

Resources