Garbage value returned for some threads? - c

I am rather facing a strange problem. This is not crucial for my work but I still want to understand this behavior. I am running three tasks in the order of their priority. I am calling one function from all of these threads with different arguments. For the highest priority thread (l3_thread) I get the right value for int J, but for other threads with low priority (l2_thread), I see garbage value for J. What is the concept that is at play here ?
Code:
int p_task(int limit1, int limit2, int sleep_time, int prio){
int i, j;
for(i=limit1; i<=limit2; i++)
{
j=j+1;
printf("J = %d \n", j);
}
return 0;
}
void *l3_thread(void *arg){
/*call to p_task*/
pthread_exit(NULL);
}
void *l2_thread(void *arg){
/*call to p_task*/
pthread_exit(NULL);
}

I see garbage value for J...
This is because the variable j in the function p_task() is not initialized.
int i, j;
for(i=limit1; i<=limit2; i++)
{
j=j+1; //j is not initialized and used
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
[C Standards#6.7.9p10]

Related

Changing the value of a variable with pointers not working

Basically I have a function called MinSubTab that is supposed to calculate the sum of the array passed and also to change the value passed in the first argument from inside the function without using return. This is done with pointers. Anyway, I think it'd be easier if I just showed you the code so here it is:
maintab.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tab.h"
int main(){
int *reftab;
int min;
reftab = (int *)malloc(sizeof(int) * NMAX);
InitTab(reftab,NMAX);
printf("\n Total: %d et min: %d", MinSumTab(&min, reftab, NMAX), min);
free(reftab);
return 0;
}
tab.c
void InitTab(int *tab, int size){
srand(time(NULL));
for (int i=0; i<size; i++){
*(tab+i) = rand() % 10;
}
}
int MinSumTab(int *min, int *tab, int size){
int total=0;
int minimum = NMAX;
int temp = *min;
for (int i=0; i<size; i++){
total += *(tab+i);
}
for (int i=0; i<size; i++){
if(*(tab+i)<minimum){
minimum = *(tab+i);
}
}
*min = minimum;
return total;
}
So the expected result here is that the sum is printed (which it is) and the minimum value of the array is printed (which it is not). Every single time the min variable equals 8 and I've no idea how to actually change the value of min from within that function.
Please help as my brain has no more capacity for rational thought, it's been 1.5 hrs and no solution in sight. Thanks
Looks like a small mistake:
You initialize minimum with NMAX, which I assume is 8 (the size of the array). 99.9% of the random numbers will be bigger. So 8 is chosen as the minimum.
What you really want is to initialize it with RAND_MAX – the maximum value rand() can return.
In C order of evaluation and argument passing is undefined.
You can of course the order yourself but it only to feed your curiosity.
#include <stdio.h>
volatile char *message[] = {
"fisrt", "second", "third", "fourth"
};
int print(size_t x)
{
printf("%s\n", message[x]);
return x;
}
int main()
{
printf("%d %d %d %d\n", print(0), print(1), print(2), print(3));
return 0;
}
Note. There is one exception from this rule.
Logical operators are evaluated form the left to the right.
if( x != NULL && *x == 5)is safe because x will not be dereferenced if it is NULL

How to implement a running variable in a recursive function

At the moment I am coding a program in which I need a variable count that increments every time I call the function. In my case I have a recursive function and want to know how many iterations the program does.
I simplified the code by computing the factorial of a number.
My first approach does not work and ends up with warning messages:
#include <stdio.h>
int factorial(unsigned int i, int *count)
{
*count += 1;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, &count);
}
int main()
{
int i = 10;
int count = 0;
printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count));
return 0;
}
warning: passing argument 2 of ‘factorial’ from incompatible pointer type
My second approach does not work either but also does not ends up with any warning messages.
#include <stdio.h>
int factorial(unsigned int i, int count)
{
count += 1;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, count);
}
int main()
{
int i = 10;
int count = 0;
printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, count));
return 0;
}
How can I make it run? Any ideas? I use Ubuntu and gcc.
There is no need for static variables, as other solutions suggest. The following is correct:
int factorial(unsigned int i, int *count)
{
*count += 1;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, count);
}
int main(void)
{
int i = 10;
int count = 0;
printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count));
return 0;
}
One note: as the order of parameter evaluation in the printf statement is not guaranteed, as I understand it the value of count in the call to printf may either be zero (it is passed before factorial was called) or may be 10 (the value after factorial was called). Therefore, main could better be written as:
int main(void)
{
int i = 10;
int count = 0;
int fact= factorial(i, &count);
printf("%d Iterations, Factorial of %d is %d\n", count, i, fact);
return 0;
}
6.5.2.2 Function calls: 10 The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
In your first case, factorial() function, count is of type int *. So, while calling the function recursively (in the return statement), do not pass address of count, just pass the count itself.
That said, as count is to be modified in the function call of factorial(), don't pass both of them (the variable and the function call which modifies the variable) in the same argument list as there is no sequence point in the elements passed as argument list, so you'll end up invoking undefined behavior.
Declare the count variable as static inside the factorial function itself.
static int count = 0;
There are two ways of solving this problem.
Declare a static variable in the recursive function to count the no of times it is called.
e.g.
int factorial(unsigned int i, int *count)
{
static int count2;
*count = ++count2;
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1, count);
}
int main()
{
int i = 10;
int count = 0, fact;
fact = factorial(i, &count);
printf("%d Iterations, Factorial of %d is %d\n", count, i, fact);
return 0;
}
Have count as a pointer to integer, which can then be updated in each function to find the number of iterations.
e.g.
int factorial(unsigned int i, int *count)
{
(*count)++;
// Remaining lines the same as first solution.
}
The second solution will only work in some special types of recursive functions where the first function calls the second and the second calls the third, etc. It will not work for example in a recursive fibbonaci sequence algorithm.
The first solution is a more general one, and will work for all conditions.

Unexpected results from passing int-value in multithreading, C

I am currently trying to learn about multi-threading in C. But I have got very unexpected results which have left me stumped. In this program, I am trying to fill up a matrix by using threads. I am creating 1024 threads, passing the i value into the function. Then I proceed to use it.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define SIZE 1024
static double a[SIZE][SIZE];
static double b[SIZE][SIZE];
static double c[SIZE][SIZE];
void*
init_matrix(void* msg)
{
int j;
int num = *((int*) msg);
printf("%d\n", num);
for (j = 0; j < SIZE; j++) {
a[num][j] = drand48();
b[num][j] = drand48();
}
pthread_exit(NULL);
}
int
main(int argc, char **argv)
{
//Init threads
pthread_t p_initThreads[SIZE];
int i,j;
for(i = 0; i< SIZE; i++)
{
pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)&i);
}
for(j = 0; j<SIZE; j++)
{
pthread_join(p_initThreads[j], NULL);
}
}
Expected results from the prinf would be; 1-2-3-4-5-6-7-8-9-10. With the possible
result of it being inorder due to of it being in threads. But the reults on my computer is this;
1-2-2-4-5-7-24-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-26-35-36-36-37-37-37-37-37-37-37-37-38-39-40
By commentating out;
for (j = 0; j < SIZE; j++) {
a[num][j] = drand48();
b[num][j] = drand48();
}
I get the result that I want. Why is that? It should not do anything to num!
You are passing the address of i as the input parameter of the thread. If you were passing the value of i, you would get 1-2-3-4-5-... . But when you pass the address, it is entirely possible that before the printf line is executed, the main thread already incremented i. And printf displays the current value of i, not the value it had at the moment of thread creation.
What you have is a race condition with multiple threads accessing the same memory location (variable i) since you are passing the address of i to all threads.
What you really wanted to do was pass the value of i. Call the pthread_create() with:
pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)i);
and read the value as:
int num = (int) msg;
instead of : int num = *((int*) msg);
You should also check if pthread_create() returns non-zero for failures. If that's the case, you are not going to get expected results.

Multithreading in c. Mutexes

My code does the following: creates N threads, each one of them increments the global variable counter M times. I am using a mutex in order to assure the final value of counter is M*N.
I would like to observe the situation without a mutex, to obtain a different value for counter, in order to proper assess the mutex's work. I commented out the mutex, but the results are the same. Should I put them to sleep for a random period of time? How should I procede?
#include <stdio.h>
#include <pthread.h>
#define N 10
#define M 4
pthread_mutex_t mutex;
int counter=0;
void *thread_routine(void *parameter)
{
pthread_mutex_lock(&mutex);
int i;
for (i=0; i<M; i++)
counter++;
pthread_mutex_unlock(&mutex);
}
int main(void)
{
pthread_t v[N];
int i;
pthread_mutex_init(&mutex,NULL);
for (i=0; i<N; i++)
{
pthread_create(&v[i],NULL,thread_routine,NULL);
}
for (i=0; i<N; i++)
{
pthread_join(v[i],NULL);
}
printf("%d %d\n",counter,N*M);
if (N*M==counter)
printf("Success!\n");
pthread_mutex_destroy(&mutex);
return 0;
}
I don't know what compiler you used, but g++ in this case would completely eliminate the threads and calculate the final value of counter at compile time.
To prevent that optimization you can make the counter variable volatile
volatile int counter=0;
As this will tell the compiler that the variable can change at any time by external resources, it is forced to not to do any optimizations on that variable that could have side effects. As an external resource could change the value, the final value might not be the result of N*M and therefore the value of counter will be calculated at run-time.
Also what WhozCraig stated in his comment will most likely apply in your case. But I think he meant M, not N.
Additionally to your original question: As you read the counter once all threads are joined, it might be worth to give each thread its own counter and sum all threads' counters when they finished computation. This way you can compute the final value without any locks or atomic operations.
Edit:
Your first test with mutex would look like this
#define N 10
#define M 10000000
pthread_mutex_t mutex;
volatile int counter=0;
void *thread_routine(void *parameter)
{
pthread_mutex_lock(&mutex);
int i;
for (i=0; i<M; i++)
counter++;
pthread_mutex_unlock(&mutex);
}
and your second test without mutex like this
#define N 10
#define M 10000000
pthread_mutex_t mutex;
volatile int counter=0;
void *thread_routine(void *parameter)
{
// pthread_mutex_lock(&mutex);
int i;
for (i=0; i<M; i++)
counter++;
// pthread_mutex_unlock(&mutex);
}
while the second test will have the expected race conditions when incrementing the counter variable.
Compilation can be done using gcc -O3 -lpthread test.c

How to save pthread_t id to an array

How can i save the id of p_thread to an array?
int i;
pthread_t t[N];
float arrayId[N];
for (i = 0; i < N; i++) {
pthread_create(&t[i], NULL, f, (void *) &i);
printf("creato il thread id=%lu\n", t[i]);
arrayId[i] = t[i];
printf("a[%d]=%f\n", i, arrayId[i]);
}
I can print it, but i'm not able to save...
I'll have to sort this array and then i'll have to execute first all the thread ordered by id
All threads will receive the same value for i because you are passing it by value (the same address).
This should fix it:
int i;
pthread_t t[N];
float arrayId[N];
int indexes[N];
for (i = 0; i < N; i++) {
indexes[i] = i;
pthread_create(&t[i], NULL, f, (void *) &indexes[i]);
printf("creato il thread id=%lu\n", t[i]);
arrayId[i] = t[i];
printf("a[%d]=%f\n", i, arrayId[i]);
}
I'll have to sort this array and then i'll have to execute first all the thread
ordered by id
pthread_create already executes a thread as man states:
The pthread_create() function starts a new thread in the calling process.
So your loop already starts N threads. Also you can't specify thread ids, they are returned when threads are created.
You don't need to save the array. You simply define a function, f, that you wish to operate on these numbers, and then, as you have done in your pthread_create(), have that function, f, as an input.
Each time pthread_create() is called the function, f, will be executed.

Resources