I have got troubles with my code.
The following code starts n threads that compete to find the max value of each diagonal of n different matrices.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <time.h>
#include <semaphore.h>
void crea_matrix(int **);
void trova_max(void *);
struct bin_sem
{
pthread_mutex_t mutex;
pthread_cond_t cond;
int cnt;
} shared= {PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER };
int n,**matrix,max;
int main ()
{
int i;
srand(time(NULL));
printf("N of matrices: \n");
scanf("%d", &n);
int **matrix = (int **)malloc(3 * sizeof(int *));
for (i=0; i<3; i++)
matrix[i] = (int *)malloc(3 * sizeof(int));
pthread_t *tids;
tids=malloc(n*sizeof(pthread_t));
for(i=0;i<n;i++)
pthread_create(tids+i,NULL,trova_max,matrix);
for(i=0;i<n;i++)
{
pthread_mutex_lock(&shared.mutex);
max=0;
crea_matrix(matrix);
shared.cnt=i;
pthread_cond_signal(&shared.cond);
pthread_mutex_unlock(&shared.mutex);
sleep(1);
}
for(i=0;i<n;i++)
pthread_join(tids[i],NULL);
}
void crea_matrix(int **matrix)
{
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
matrix[i][j]=rand()%101;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",matrix[i][j]);
printf("\n");
}
}
void trova_max(void* arg)
{
int i=0, j=0;
int **arr2d;
arr2d=(int**)arg;
do
{
pthread_mutex_lock(&shared.mutex);
pthread_cond_wait(&shared.cond,&shared.mutex);
printf("\nThread: %ld took control of the mutex...\n",(long int) pthread_self());
for(i=0;i<3;i++)
{
if(arr2d[i][i]>max)
max=arr2d[i][i];
printf("\nFirst diag max: %d\n",max);
}
i=0;
for (j=2;j>=0;j--)
{
printf("\nSecond diag max: %d\n",max);
if (arr2d[i][j]>max)
max=arr2d[i][j];
i++;
}
printf("Max found: %d,matrix n° %d", max,shared.cnt);
pthread_mutex_unlock(&shared.mutex);
} while(shared.cnt !=n-1);
pthread_exit(NULL);
}
The thing is, most of my code works, but when the max evaluations are done, only 1 thread gets access to the pthread_exit(NULL); line.
I am struggling to find a solution, Hope you can help me.
Thanks.
Referring to this question: Is it guaranteed that pthread_cond_signal will wake up a waiting thread?
It is possible that the remaining threads are still blocked on pthread_cond_wait. Doing a final pthread_cond_broadcast before the join will release all the blocked threads.
However, this solution will bring its own set of problems as all the threads will eventually execute the body of the loop. You may have to add an extra check for shared.cnt != n-1. That has to be done atomically though as noticed in one of the comments.
Related
First of all i hope you are all safe. I am trying to pass an array which contains the threadIDs of the threads created in C. I know the program is full of errors but I am getting one error that I don't know how to resolve. At the line where i write threadID[i]=(int*)tid[i]; I get invalid type conversion. What Im trying to do in convert void* to int and I get that error. I am pretty bad at C but I am trying to learn. If I could get any help I would appreciate it
Thank you
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
int x=0;
void* printMsg(void *tid)
{
pthread_t id = pthread_self();
int nthreads;
//Get the number of threads
nthreads= sizeof(tid);
//Copy thread array from main to threadID array
int *threadID[nthreads];
;
for(int i=0;i<nthreads;i++)
threadID[i]=(int*)tid[i];
if(pthread_equal(id,threadID[x]))
{
printf("%d\n",x);
x++;
}
while(1);
}
int main()
{
int i=0;
int n=0;
printf("Enter number of threads : ");
scanf("%d",&n);
pthread_t tid[n];
for(i=0;i<n;i++)
{
pthread_create(&(tid[i]), NULL, &printMsg, (void*)tid);
}
for (i=0;i<n;i++)
{
pthread_join(tid[i], NULL);
}
sleep(5);
return 0;
}
The ideal way to do this is to let the thread know which thread it is at creation time. You can do that by passing the thread ID as an argument. Here's a way you can do that:
void *printMsg(void *tnum_p) {
int tnum = *(int *)tnum_p;
printf("%d\n", tnum);
return NULL;
}
int main() {
int i = 0;
int n = 0;
printf("Enter number of threads: ");
scanf("%d", &n);
pthread_t tid[n];
int tnum[n];
for(i = 0; i < n; i++) {
tnum[i] = i;
pthread_create(&(tid[i]), NULL, &printMsg, &(tnum[i]));
}
for (i = 0; i < n; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}
One might think that we could just pass &i instead of &(tnum[i]); this would compile without any error, but then each thread would receive the same address, and it would be up to the luck and timing what each thread finds there (i.e. you'd almost certainly have repeated numbers).
(I also prefer tid + i and tnum + i instead of &(tid[i]) and &(tnum[i]), but that's just me.)
If you need to send any other information, then make a struct to carry everything you need, instead of passing an int.
This is a program to make the (square) sum of an array using threads. It works fine if the array elements are up to about 2.000.000 but after that I get a "Segmentation fault (core dumped)" error. Could it be because I am using ubuntu in a virtual machine and I have allocated 4GB of RAM in it?
Thank you for your time!
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
int part = 0;
int local_elements = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* square_sum(void* arg);
int main()
{
int threads, total_elements;
int i;
void *loc_sum = NULL;
long long total_sum = 0;
printf("Give the number of threads: ");
scanf("%d", &threads);
/*-----Fixed big size array-----*/
total_elements = 2000000; // <--- If this value gets big I get that error
local_elements = total_elements/threads;
int element_array[total_elements];
for (int i=0; i<total_elements; i++) {
//Filling all the positions with 1s
element_array[i] = 1;
}
//Creating the threads
pthread_t newthread[threads];
for (int i=0; i<threads; i++) {
//The thread function gets the element array
pthread_create(&newthread[i], NULL, square_sum, (void *)element_array);
}
//Waiting for each thread to finish and creating the total_sum
for (int i=0; i<threads; i++) {
pthread_join(newthread[i], (void*) &loc_sum);
printf("Thread %d returned the local_sum: %d \n", i, (int)loc_sum);
total_sum += (int)loc_sum;
}
printf("\nThe total square sum of the array is: %lld\n", total_sum);
return 0;
}
void* square_sum(void* arg) {
intptr_t local_sum = 0;
int *element_array = (int *) arg;
//--- Start of critical section ---
pthread_mutex_lock(&mutex);
//Each thread computes its part
int thread_part = part++;
for (int i = thread_part*local_elements; i < (thread_part+1)*local_elements; i++) {
local_sum += element_array[i] * element_array[i];
//printf("Thread %d says -- element %d is: %d \n", thread_part, i, element_array[i]);
}
pthread_mutex_unlock(&mutex);
//--- End of critical section ---
return ((void*)local_sum);
}
Kiran Biradar is correct. I get correct results with ulimit -s 80000 (I ran as root to set high ulimit) for this hacked version of your program. Alternatively, allocating the array on the heap or as static should also avoid the stack size problem, as mentioned by another commenter.
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int part = 0;
int local_elements = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* square_sum(void* arg) {
int* local_sum = (int*)malloc(sizeof(int));
int *element_array = (int *) arg;
//--- Start of critical section ---
pthread_mutex_lock(&mutex);
//Each thread computes its part
int thread_part = part++;
for (int i = thread_part*local_elements; i <
(thread_part+1)*local_elements; i++) {
*local_sum += element_array[i] * element_array[i];
//printf("Thread %d says -- element %d is: %d \n", thread_part, i,
//element_array[i]);
}
pthread_mutex_unlock(&mutex);
//--- End of critical section ---
return local_sum;
}
int main()
{
int threads, total_elements;
int i;
int* loc_sum;
long long total_sum = 0;
printf("Give the number of threads: ");
scanf("%d", &threads);
/*-----Fixed big size array-----*/
total_elements = 2000000; // <--- If this value gets big I get that error
local_elements = total_elements/threads;
int element_array[total_elements];
for (int i=0; i<total_elements; i++) {
//Filling all the positions with 1s
element_array[i] = 1;
}
//Creating the threads
pthread_t newthread[threads];
for (int i=0; i<threads; i++) {
//The thread function gets the element array
pthread_create(&newthread[i], NULL, square_sum, element_array);
}
//Waiting for each thread to finish and creating the total_sum
for (int i=0; i<threads; i++) {
pthread_join(newthread[i], (void**)&loc_sum);
printf("Thread %d returned the local_sum: %d \n", i, *loc_sum);
total_sum += *(int*)loc_sum;
free(loc_sum);
printf("loc_sum %d\n", *loc_sum);
}
printf("\nThe total square sum of the array is: %lld\n", total_sum);
return 0;
}
Your problem is that
int element_array[total_elements];
is too big to be allocated in the in the stack. 2.000.000 positions requires 8Mb of memory, and Linux's default stack size is 8Mb, as can be seen by running ulimit -s. To fix it, you can use malloc to allocate it in the heap, or use the static keyword, as it will allocate the array in the .data segment, which usually has a 4Gb limit in amd64 machines.
I would like to calculate a mathematic summation in c using threads.
(∑x^i ,From 0 to N) Each threads should calculate each terms of the summation and finally in the main the program should sum all of them and print them.
How should I make the number of threads dynamically?
Here is my code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <math.h>
pthread_t sadaf[10];
int i,a[10];
long int x,N;
int sum=0;
pthread_mutex_t mtx;
void *Myfun(void *tid)
{
int *ThreadID=(int *)tid;
pthread_mutex_lock(&mtx);
printf("The thread with id of %d calculated x^i\n",*ThreadID);
a[*ThreadID]=pow(x,*ThreadID);
sum=sum+a[*ThreadID];
pthread_mutex_unlock(&mtx);
}
int main()
{
int d[10] = {0};
printf("->**************************************************************************<-\n");
printf("This program will calculate the following function:\n-> ∑x^i ,From 0 to N \n");
printf("->**************************************************************************<-\n");
printf("Please enter x:\n");
scanf("%ld",&x);
printf("Please enter N:\n");
scanf("%ld",&N);
for (i=0; i<N; i++)
{
d[i] = i;
pthread_create(&sadaf[i],NULL,Myfun,(void *)&d[i]);
}
for (i=0; i<N; i++)
{
pthread_join(sadaf[i],NULL);
}
printf("The sum is: %d\n",sum);
}
The d array can hold 10 values, so if N is greater than 10, you have an out of bounds problem:
int d[10] = {0};
...
for (i=0; i<N; i++)
{
d[i] = i; // if i > 10 => you access out of bounds => problem
You have the same problem with other arrays too.
You have only 10 pthreads defined at the beginning.
pthread_t sadaf[10];
Creating more than 10 threads will cause the undefined behaviour.
I want to create 2 threads, one does the max and one gives the average of a list of numbers entered in the command line.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <limits.h>
void * thread1(int length, int array[] )
{
int ii = 0;
int smallest_value = INT_MAX;
for (; ii < length; ++ii)
{
if (array[ii] < smallest_value)
{
smallest_value = array[ii];
}
}
printf("smallest is: %d\n", smallest_value);
}
void * thread2()
{
printf("\n");
}
int main()
{
int average;
int min;
int max;
int how_many;
int i;
int status;
pthread_t tid1,tid2;
printf("How many numbers?: ");
scanf("%d",&how_many);
int ar[how_many];
printf("Enter the list of numbers: ");
for (i=0;i<how_many;i++){
scanf("%d",&ar[i]);
}
//for(i=0;i<how_many;i++)
//printf("%d\n",ar[i]);
pthread_create(&tid1,NULL,thread1(how_many,ar),NULL);
pthread_create(&tid2,NULL,thread2,NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
exit(0);
}
I just made the first thread, which is to print out the min. number, but I have the following errors when compiling:
How many numbers?: 3
Enter the list of numbers: 1
2
3
Smallest: 1
Segmentation fault
How should I go on and fix the seg. fault?
You can't pass arguments like you're trying to in pthread_create.
Create a structure like:
struct args_t
{
int length;
int * array;
};
then initialize a structure with your array and length.
args_t *a = (args_t*)malloc(sizeof(args_t));
//initialize the array directly from your inputs
Then do
pthread_create(&tid1,NULL,thread1,(void*)a);
Then just cast the argument back to an args_t.
Hope that helps.
I am a beginner in C programming and I am trying to perform mutex on the program below, but I'm not getting the proper output.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREAD 4
void *func(void *p);
int counter=0,a=2;
pthread_mutex_t mutexsum = PTHREAD_MUTEX_INITIALIZER;
main()
{
int i,rc;
pthread_t threadid[NUM_THREAD];
for(i = 0; i< NUM_THREAD; i++)
{
a = a + i;
printf("Value of a is %d\n",a);
rc = pthread_create(&threadid[i],NULL,func,(void *)a);
if(rc)
{
printf("Error in thred creation thread[%d] %d",i,rc);
}
}
for(i = 0; i< NUM_THREAD; i++)
{
pthread_join(threadid[i],NULL);
}
printf("Final value of counter is %d\n",counter);
pthread_exit(NULL);
}
void *func(void *p)
{
int i;
i = (int) p;
pthread_mutex_lock(&mutexsum);
counter = counter+a;
printf("%d\n",counter);
pthread_mutex_unlock(&mutexsum);
pthread_exit(NULL);
}
As per the above program and my understanding, the desired output will be 18, but it's giving 32.
func uses a to increment. I'm guessing you meant to increment by i. As it is, by the time each thread runs, a must be at its final value of 8, so you are adding 8 to counter four times.
You are not using i in your thread function, but a.