Dynamic pthread spawning sync required(???) - c

I'm trying to write some code using posix threads but I'm stuck from the first step and to be honest I can't realise why. I know that my problem has probably to do with some sort of synchronisation but I can't figure it out.
What I have in main is the following:
while(1){
int x = getX();
pthread_t t;
printf("Main: %d\n",x);
pthread_create(&t, NULL, process_x, &x);
}
When I try to print the x value from the main and also the process_x function what I get is something like this:
Main: 1
Main: 2
Main: 3
Main: 4
Main: 5
Process_x: 5
What do I miss here?
---- EDIT -----
OK, maybe I need to provide some more info. The getX function receives data from a socket and returns an identifier while for our needs now the process_x just prints the argument it receives.

You need to consider that you pass the address of x to a thread, and then without waiting for the thread to finish printing, you modify it's value. Obviously, this will mean that if a few iterations are over before the thread gets to print it's value, the value would have changed.
Two Ways around this:
1) Use a pthread_join and wait for the thread to finish. This is esseentially useless. Because then what is the point of spawning the new thread?
OR
2) Allocate a new address for each thread, and let the thread free it after it finishes printing.
i.e. malloc a new integer, assign x to that integer, pass the new mallocd integer to the thread, let the thread free it when done.

A thread will not be executed as soon as you create it using a call to pthread_create. The scheduler can decide to keep it in queue. During that time your while loop has run 5 times and value of x might also have changed to 5. Now when your thread(s) is(are) eventually scheduled, it(they) only sees the latest value of your x and hence print(s) only 5.
I strongly suspect that Process_x was printed only once?
There is no default way to get pthreads executed in any specific order. You need to use some synchrnization techniques like semaphores. Also if you want to see Process_x print all your values, convert x into an array and pass x[i] as argument to pthread_create

Apparently using malloc doesn't work because it sets x to 0 so the process always reads 0. But thanks to everyones ideas I finally made it work using a condition variable and now everything is ok. Here is the code.
int main{
pthread_t t;
int x;
while(1){
pthread_mutex_lock(&receive);
x = getX();
printf("Main: %d\n",x);
pthread_create(&t, NULL, process_x, &x);
pthread_cond_wait(&goOn, &receive);
pthread_mutex_unlock(&receive);
}
}
void *process_x(void* arg){
pthread_mutex_lock(&receive);
int x = *(int *) arg;
pthread_cond_signal(&goOn);
pthread_mutex_unlock(&receive);
}

Related

pthreads in C: How can I stop the threads from interfering with each other?

I'm new to using pthreads. I want to create a program where six different threads will each output a different number. The threads can run in any order, however, each thread should run only once.
So, a possible output would be:
Thread: 5
Thread: 2
Thread: 3
Thread: 6
Thread: 1
Thread: 4
Or it could be in any other order.
#include<stdio.h>
#include<pthread.h>
void *apples(void *void_apple_num){
int *thread_num = (int *) void_apple_num;
printf("Thread: %d\n", *thread_num);
return NULL;
}
int main(){
pthread_t threads[6];
int apple_num;
for(apple_num=0; apple_num<6; apple_num++){
pthread_create(&threads[apple_num], NULL, apples, &apple_num);
}
for(apple_num=0; apple_num<6; apple_num++){
pthread_join(threads[apple_num], NULL);
}
return 0;
}
When I run the program, I have this problem of the threads interfering with each other. I am not sure if some of the threads are running twice? However, I think the problem is some of the threads are using the apple_num pointer from a different thread.
Here are two sample outputs I got:
Output 1:
Thread: 5
Thread: 0
Thread: 1
Thread: 1
Thread: 2
Thread: 2
Output 2:
Thread: 1
Thread: 4
Thread: 4
Thread: 5
Thread: 1
Thread: 1
I don't fully understand what is causing the problem. I've heard that threads can sometimes share variables? I don't know if I should use a mutex lock to somehow get the threads to run one-at-a-time.
How can I edit my code to solve this?
If somebody else has asked a similar question, please direct me to their question. I couldn't find anything when I researching.
Each of your threads gets a pointer to the very same local variable apple_num which is being changed in the loop by the main thread. Since threads start asynchronously, the value of local variable apple_num in the main thread is indeterminate from the perspective of any other thread.
You need to pass a copy of that variable to each thread.
One fix is to cast int to void* and back:
void *apples(void* apple_num){
int thread_num = (int)void_apple_num;
...
pthread_create(&threads[apple_num], NULL, apples, (void*)apple_num);
As they mention in the comments, intptr_t and uintptr_t (from <stdint.h>) may be more appropriate for round-trip without loss, e.g. uintptr_t -> void* -> uintptr_t. But C standard doesn't require any integers to round-trip to void* and back, it only requires void* -> intptr_t and back.
In a more realistic scenario, you may like to pass more than just one integer to a thread, namely, a struct. And that's the rationale for the thread start function to receive a single void* argument - it can point to an object of any data type (POSIX requires void* to also be able to store function pointers).
An example of passing a structure to a thread (without relying on implementation-defined conversion of integers to void* and back):
struct ThreadArgs {
int thread_num;
// More data members, as needed.
};
void* apples(void* arg){
struct ThreadArgs* a = arg;
printf("Thread: %d\n", a->thread_num);
free(arg);
return NULL;
}
int main() {
pthread_t threads[6];
struct ThreadArgs* a;
int apple_num;
for(apple_num=0; apple_num<6; apple_num++){
a = malloc(sizeof *a);
a->thread_num = apple_num;
pthread_create(&threads[apple_num], NULL, apples, a);
}
for(apple_num=0; apple_num<6; apple_num++)
pthread_join(threads[apple_num], NULL);
return 0;
}
Note, that you don't have to allocate the thread arguments structure on the heap (malloc). If you pass an automatic variable (on the stack) to a thread, you must make sure that the variable is unchanged and still exists when the thread accesses it. Allocating the thread arguments structure from the heap is the safest and solves this problem at the expense of malloc/free calls.

c multithreading conflicts

I'm trying to use multithreading to allow two tasks to run in parallel within one DLL, but my application keeps crashing, apparently due to some bad resource conflict management; here are the details:
I need to call the same function(DoGATrainAndRun) from a certain point along the main logic flow, passing a different value for one of the parameters, let the two run, then go back to the main logic flow, and use the two (different) sets of values returned from the 2 calls.
(this is in the main header file):
typedef struct
{
int PredictorId;
int OutputType;
int Delta;
int Scale;
int Debug;
FILE* LogFile;
int TotalBars;
double CBaseVal;
double* HVal;
int PredictionLen;
double*** Forecast;
} t;
(This is in the main logic flow):
hRunMutex=CreateMutex(NULL, FALSE, NULL);
arg->OutputType=FH;
handle= (HANDLE) _beginthread( DoGATrainAndRun, 32768, (void*) arg);
arg->OutputType=FL;
handle= (HANDLE) _beginthread( DoGATrainAndRun, 32768, (void*) arg);
do {} while (hRunMutex!=0);
CloseHandle(hRunMutex);
(this is at the end of DoGaTrainAndRun):
free(args);
ReleaseMutex( hRunMutex );
I'm pretty new to multi-threading, and I can't seem to figure this one out...
There's a few things:
First, you're passing the same structure into both threads but just changing the OutputType value. If possible that the first thread will see FL and never see the value FH. The reason for this is how threads are scheduled. It's valid for your first thread to start and then be suspended. Then, your main thread creates the second thread, having set OutputType to FL. This thread starts and the first one is resumed as well. However, the first one now sees OutputType as FL.
Next, both threads are using the same structure, but one of them is freeing the memory. If the other thread is still using it after the other releases then you'll get undefined behaviour in the thread that is still using it. This will probably result in a crash.
You're attempt to wait for the threads to exit is wrong. You don't need the mutex and you certainly don't need to be spinning of it testing for zero. Just use WaitForMultipleObjects:
HANDLE handles[2];
handles[0] = (HANDLE)_beginthread(...);
handles[1] = (HANDLE)_beginthread(...);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
This will stop your main thread from spinning around wasting cpu cycles. When the wait returns you'll know both threads have finished.
Putting this all together should give you something like this:
HANDLE handles[2];
t *arg1=malloc(sizeof(t));
arg1->OutputType=FH
handles[0] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg1);
t *arg2=malloc(sizeof(t));
arg2->OutputType=FL
handles[1] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg2);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
free(arg1);
free(arg2)
And don't release any memory in DoGATrainAndRun.

why using pthread_exit?

I'm trying to figure out the usage of pthread_exit using this example code:
void* PrintVar(void* arg)
{
int * a = (int *) arg; // we can access memory of a!!!
printf( "%d\n", *a);
}
int main(int argc, char*argv[])
{
int a, rc;
a = 10;
pthread_t thr;
pthread_create( &thr, NULL, PrintVar, &a );
//why do I need it here?//
pthread_exit(&rc); /* process continues until last
threads termintates */
there are two things I'm not quite sure about :
when we are using pthread_create - I'm passing 'a' parameter's address,
but is this paramter being "saved" under "arg" of the PrintVar function?
for example if I was using : PrintVar(void *blabla) , and wanted to pass 2 parameters from main function : int a = 10, int b= 20 .. how can I do that?
Why the pthread_exit needed? it means - wait for proccess to end - but what scenario can I get if I won't use that line?
thanks alot!
when we are using pthread_create - I'm passing 'a' parameter's address, but is this paramter being "saved" under "arg" of the PrintVar function?
The "original" a (the one defined in main) is not being copied, you are only passing around a pointer to it.
for example if I was using : PrintVar(void *blabla) , and wanted to pass 2 parameters from main function : int a = 10, int b= 20 .. how can I do that?
Put those two values in a struct and pass a pointer to such struct as argument to pthread_create (PrintVar, thus, will receive such a pointer and will be able to retrieve the two values).
and my second question is why the pthread_exit needed? it means - wait for proccess to end - but what scenario can I get if I won't use that line?
pthread_exit terminates the current thread without terminating the process if other threads are still running; returning from main, instead, is equivalent to calling exit which, as far as the standard is concerned, should "terminate the program" (thus implicitly killing all the threads).
Now, being the C standard thread-agnostic (until C11) and support for threading in the various Unixes a relatively recent addition, depending from libc/kernel/whatever version exit may or may not kill just the current thread or all the threads.
Still, in current versions of libc, exit (and thus return from main) should terminate the process (and thus all its threads), actually using the syscall exit_group on Linux.
Notice that a similar discussion applies for the Windows CRT.
The detached attribute merely determines the behavior of the system when the thread terminates; it does not
prevent the thread from being terminated if the process terminates using exit(3) (or equivalently, if the
main thread returns).

Wrong thread finish in C? [duplicate]

This question already has answers here:
Wrong thread IDs in a multithreaded C program?
(2 answers)
Closed 8 years ago.
I compiled this code and the 99th threads that it's been created keeps creating more than one thread of number 99. Instead if i insert values from 1-10 or something small then the results are quite normal.
Here is the code.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
pthread_attr_t attr;
void* test(void *a)
{
int i=*((int *)a);
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
usleep(10000);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
int main()
{
int i=0,j=0;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
pthread_t thread[100];
for (i=0;i<100;i++)
{
j=i;
pthread_create(&thread[i],&attr,test,&j);
}
for (i=0;i<100;i++)
pthread_join(thread[i],NULL);
return 0;
}
i get:
..../*Normal Results*/
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
Why is this happening?
You need to keep all theadIds
int indexes[PTHREAD_COUNT];
for (i=0;i<100;i++) {
indexes[i] = i;
pthread_create(&thread[i], &attr, test, &indexes[i]);
}
Each thread is passed the same pointer to the same stack location (j) in your main thread. Without further synchronisation, its undefined when each thread will be scheduled and will run and access j before printing its value.
There are lots of ways you could print out a unique number from each thread, including
malloc a struct which includes (or is) this number in the main thread. Pass it to the child threads which are then responsible for freeing it
(Suggested by Brian Roche below) Declare an array of 100 ints, with values 0, 1, 2, etc. Pass the address of a different array item to each thread.
have each thread lock a mutex then copy/increment a global counter. The mutex could be passed into the thread or another global
pass a semaphore into each thread, signalling it once the number has been accessed. Wait on this semaphore in the main thread
Note that options 3 & 4 involve serialising startup of the threads. There's little point in running multiple threads if you do much of this!
i is the same address as j in your main code, and you sleep of 30 ms in the threads. So all threads have time to run until the first mutex call, then they all stop for (a little over) 30ms, and then print they have finished. Of course, i in the main loop is now 99, because you are finished with the pthread_join loop.
You need to have an array of "j" values [assuming you want all threads to run independently]. Or do something else. It all depends on what you are actually wanting to do.
you are passing the same memory location (&j) as the pointer to data a.
when threads start, they print out the value just assigned to j, which looks OK
But then only one get the lock and went to sleep, all others thus blocked. when the nightmare is over, memory location "a", of course, has a int value 99.

Linux - force single-core execution and debug multi-threading with pthread

I'm debugging a multi-threaded problem with C, pthread and Linux. On my MacOS 10.5.8, C2D, is runs fine, on my Linux computers (2-4 cores) it produces undesired outputs.
I'm not experienced, therefore I attached my code. It's rather simple: each new thread creates two more threads until a maximum is reached. So no big deal... as I thought until a couple of days ago.
Can I force single-core execution to prevent my bugs from occuring?
I profiled the programm execution, instrumenting with Valgrind:
valgrind --tool=drd --read-var-info=yes --trace-mutex=no ./threads
I get a couple of conflicts in the BSS segment - which are caused by my global structs and thread counter variales. However I could mitigate these conflicts with forced signle-core execution because I think the concurrent sheduling of my 2-4 core test-systems are responsible for my errors.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_THR 12
#define NEW_THR 2
int wait_time = 0; // log global wait time
int num_threads = 0; // how many threads there are
pthread_t threads[MAX_THR]; // global array to collect threads
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; // sync
struct thread_data
{
int nr; // nr of thread, serves as id
int time; // wait time from rand()
};
struct thread_data thread_data_array[MAX_THR+1];
void
*PrintHello(void *threadarg)
{
if(num_threads < MAX_THR){
// using the argument
pthread_mutex_lock(&mut);
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
// updates
my_data->nr = num_threads;
my_data->time= rand() % 10 + 1;
printf("Hello World! It's me, thread #%d and sleep time is %d!\n",
my_data->nr,
my_data->time);
pthread_mutex_unlock(&mut);
// counter
long t = 0;
for(t = 0; t < NEW_THR; t++){
pthread_mutex_lock(&mut);
num_threads++;
wait_time += my_data->time;
pthread_mutex_unlock(&mut);
pthread_create(&threads[num_threads], NULL, PrintHello, &thread_data_array[num_threads]);
sleep(1);
}
printf("Bye from %d thread\n", my_data->nr);
pthread_exit(NULL);
}
return 0;
}
int
main (int argc, char *argv[])
{
long t = 0;
// srand(time(NULL));
if(num_threads < MAX_THR){
for(t = 0; t < NEW_THR; t++){
// -> 2 threads entry point
pthread_mutex_lock(&mut);
// rand time
thread_data_array[num_threads].time = rand() % 10 + 1;
// update global wait time variable
wait_time += thread_data_array[num_threads].time;
num_threads++;
pthread_mutex_unlock(&mut);
pthread_create(&threads[num_threads], NULL, PrintHello, &thread_data_array[num_threads]);
pthread_mutex_lock(&mut);
printf("In main: creating initial thread #%ld\n", t);
pthread_mutex_unlock(&mut);
}
}
for(t = 0; t < MAX_THR; t++){
pthread_join(threads[t], NULL);
}
printf("Bye from program, wait was %d\n", wait_time);
pthread_exit(NULL);
}
I hope that code isn't too bad. I didn't do too much C for a rather long time. :) The problem is:
printf("Bye from %d thread\n", my_data->nr);
my_data->nr sometimes resolves high integer values:
In main: creating initial thread #0
Hello World! It's me, thread #2 and sleep time is 8!
In main: creating initial thread #1
[...]
Hello World! It's me, thread #11 and sleep time is 8!
Bye from 9 thread
Bye from 5 thread
Bye from -1376900240 thread
[...]
I don't now more ways to profile and debug this.
If I debug this, it works - sometimes. Sometimes it doesn't :(
Thanks for reading this long question. :) I hope I didn't share too much of my currently unresolveable confusion.
Since this program seems to be just an exercise in using threads, with no actual goal, it is difficult to suggest how treat your problem rather than treat the symptom. I believe can actually pin a process or thread to a processor in Linux, but doing so for all threads removes most of the benefit of using threads, and I don't actually remember how to do it. Instead I'm going to talk about some things wrong with your program.
C compilers often make a lot of assumptions when they are doing optimizations. One of the assumptions is that unless the current code being examined looks like it might change some variable that variable does not change (this is a very rough approximation to this, and a more accurate explanation would take a very long time).
In this program you have variables which are shared and changed by different threads. If a variable is only read by threads (either const or effectively const after threads that look at it are created) then you don't have much to worry about (and in "read by threads" I'm including the main original thread) because since the variable doesn't change if the compiler only generates code to read that variable once (remembering it in a local temporary variable) or if it generates code to read it over and over the value is always the same so that calculations based on it always come out the same.
To force the compiler not do this you can use the volatile keyword. It is affixed to variable declarations just like the const keyword, and tells the compiler that the value of that variable can change at any instant, so reread it every time its value is needed, and rewrite it every time a new value for it is assigned.
NOTE that for pthread_mutex_t (and similar) variables you do not need volatile. It if were needed on the type(s) that make up pthread_mutex_t on your system volatile would have been used within the definition of pthread_mutex_t. Additionally the functions that access this type take the address of it and are specially written to do the right thing.
I'm sure now you are thinking that you know how to fix your program, but it is not that simple. You are doing math on a shared variable. Doing math on a variable using code like:
x = x + 1;
requires that you know the old value to generate the new value. If x is global then you have to conceptually load x into a register, add 1 to that register, and then store that value back into x. On a RISC processor you actually have to do all 3 of those instructions, and being 3 instructions I'm sure you can see how another thread accessing the same variable at nearly the same time could end up storing a new value in x just after we have read our value -- making our value old, so our calculation and the value we store will be wrong.
If you know any x86 assembly then you probably know that it has instructions that can do math on values in RAM (both getting from and storing the result in the same location in RAM all in one instruction). You might think that this instruction could be used for this operation on x86 systems, and you would almost be right. The problem is that this instruction is still executed in the steps that the RISC instruction would be executed in, and there are several opportunities for another processor to change this variable at the same time as we are doing our math on it. To get around this on x86 there is a lock prefix that may be applied to some x86 instructions, and I believe that glibc header files include atomic macro functions to do this on architectures that can support it, but this can't be done on all architectures.
To work right on all architectures you are going to need to:
int local_thread_count;
int create_a_thread;
pthread_mutex_lock(&count_lock);
local_thread_count = num_threads;
if (local_thread_count < MAX_THR) {
num_threads = local_thread_count + 1;
pthread_mutex_unlock(&count_lock);
thread_data_array[local_thread_count].nr = local_thread_count;
/* moved this into the creator
* since getting it in the
* child will likely get the
* wrong value. */
pthread_create(&threads[local_thread_count], NULL, PrintHello,
&thread_data_array[local_thread_count]);
} else {
pthread_mutex_unlock(&count_lock);
}
Now, since you would have changed the num_threads to volatile you can atomically test and increment the thread count in all threads. At the end of this local_thread_count should be usable as an index into the array of threads. Note that I did not create but 1 thread in this code, while yours was supposed to create several. I did this to make the example more clear, but it should not be too difficult to change it to go ahead and add NEW_THR to num_threads, but if NEW_THR is 2 and MAX_THR - num_threads is 1 (somehow) then you have to handle that correctly somehow.
Now, all of that being said, there may be another way to accomplish similar things by using semaphores. Semaphores are like mutexes, but they have a count associated with them. You would not get a value to use as the index into the array of threads (the function to read a semaphore count won't really give you this), but I thought that it deserved to be mentioned since it is very similar.
man 3 semaphore.h
will tell you a little bit about it.
num_threads should at least be marked volatile, and preferably marked atomic too (although I believe that the int is practically fine), so that at least there is a higher chance that the different threads are seeing the same values. You might want to view the assembler output to see when the writes of num_thread to memory are actually supposedly taking place.
https://computing.llnl.gov/tutorials/pthreads/#PassingArguments
that seems to be the problem. you need to malloc the thread_data struct.

Resources