I'm writing a multi-threaded program in c that takes in a list of numbers from the command line, then uses 3 seperate threads to get the average, max number, and min number. I completed it, but I'm not getting the correct output and I'm quite confused, because the reason it's not working is because my index variable in my threads is not incrementing. It just stays at 0 no matter what, even when trying both a while and for loop. Here is my code:
Note: I'm coding on Linux
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
int sum =0;
int num;
int count;
int max;
int min;
float average;
void* Thread_Avg(void *arg)
{
int i = 0;
int *array = (int *)arg;
while (i < count)
{
printf("%.f\n",i);
sum += array[i];
i +=1;
}
average = sum/count;
pthread_exit(0);
}
void* Thread_max(void *arg)
{
i = 0;
int *array = (int *)arg;
for (i = 0; i < count; i++)
//printf("%.f",max);
{
if(i ==0)
{
max = array[i];
}
else if(max < array[i])
{
max = array[i];
}
}
pthread_exit(0);
}
void* Thread_min(void *arg)
{
int i = 0;
int *array = (int *)arg;
for (i = 0; i < count; i++)
{
if (array[i] < min)
{
min = array[i];
}
}
pthread_exit(0);
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Usage: %s <at least one integer as input>\n", argv[0]);
return 0;
}
int *num = (int *)malloc((argc-1)*sizeof(int));
int i;
for (i =1; i <argc; i++)
{
num[i-1] = atoi(argv[i]);
count++;
}
//count = argc;
pthread_t thread1, thread2, thread3;
pthread_create(&thread1, NULL, Thread_Avg, (void *)num);
pthread_create(&thread2, NULL, Thread_max, (void *)num);
pthread_create(&thread3, NULL, Thread_min, (void *)num);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
printf("The average value is %.f\n", average);
printf("The minimum value is %.f\n", min);
printf("The maximum value is %.f\n", max);
return 0;
}
incorrect Output: (the zeroes are just from my print statement to check if i was actually being incremented, which it's not. It's stuck at 0) My average, max, and min are also not calculating properly
gcc Program.c -pthread
os#debian:~$ ./a.out 1 2 3 4 5
0
0
0
0
The average value is 2
The minimum value is 2
The maximum value is 2
Your min algorithm won't work correctly as the min variable is initialized to 0. If all input values are >0, your min will be incorrectly 0. The algorithm for max has the extra check and works correctly.
You also have a few printf format bugs in your program that will lead to incorrect display of values. You should enable warnings in your compiler, for instance by adding the -Wall flag or equivalent, to help identify these.
printf("%.f\n",i); should be printf("%d\n",i);
printf("The minimum value is %.f\n", min); should be printf("The minimum value is %d\n", min);
printf("The maximum value is %.f\n", max); should be printf("The maximum value is %d\n", max);
You probably need to read a lot more about how threads work and what they are useful for. Your threads are sharing global variables (including i), and updating them without any regard to the other threads that are relying upon them.
If you change the section of your main program to this:
pthread_create(&thread1, NULL, Thread_Avg, (void *)num);
pthread_join(thread1, NULL);
pthread_create(&thread2, NULL, Thread_max, (void *)num);
pthread_join(thread2, NULL);
pthread_create(&thread3, NULL, Thread_min, (void *)num);
pthread_join(thread3, NULL);
Do you get the expected results? Yes, so the next step is why. It is because they are no longer simultaneously updating / relying on these global variables. So, your task is:
Figure out which variables do not need to be shared.
Investigate methods of protecting the ones that need it.
Repeat, until you can convince somebody that what you have works.
Also, programs are meant to be read. Indenting is a basic visual organisation which enables people to rapidly grasp the concepts a program is expressing. Please learn about it; but until you do, imitate the masters, like the authors of C (Kerningham and Ritchie); or at the very least, install indent and run your code through it periodically. You will be amazed how much easier it is to understand a program that has a reasonable notion of indentation.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
float sum = 0; //use sample type with average
int num;
int count;
int max;
int min;
float average;
void* Thread_Avg(void *arg)
{
int i = 0;
int *array = (int *)arg;
while (i < count)
{
printf("%d\n",i); //%d for int
sum += array[i];
i +=1;
}
average = sum/count;
pthread_exit(0);
}
void* Thread_max(void *arg)
{
int i = 0;
int *array = (int *)arg;
for (i = 0; i < count; i++)
//printf("%.f",max);
{
if(i ==0)
{
max = array[i];
}
else if(max < array[i])
{
max = array[i];
}
}
pthread_exit(0);
}
void* Thread_min(void *arg)
{
int i = 0;
int *array = (int *)arg;
for (i = 0; i < count; i++)
{
if (array[i] < min)
{
min = array[i];
}
}
pthread_exit(0);
}
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("Usage: %s <at least one integer as input>\n", argv[0]);
return 0;
}
int *num = (int *)malloc((argc-1)*sizeof(int));
int i;
for (i =1; i <argc; i++)
{
num[i-1] = atoi(argv[i]);
count++;
}
//count = argc;
pthread_t thread1, thread2, thread3;
pthread_create(&thread1, NULL, Thread_Avg, (void *)num);
pthread_create(&thread2, NULL, Thread_max, (void *)num);
pthread_create(&thread3, NULL, Thread_min, (void *)num);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
printf("The average value is %.f\n", average);
printf("The minimum value is %d\n", min); //%d for int
printf("The maximum value is %d\n", max); //%d for int
return 0;
}
I tried to run it on my machine and it works:
$ ./main 1 2 3 4 5
0
1
2
3
4
The average value is 3
The minimum value is 0
The maximum value is 5
Related
I'm trying to write a code that prints "Hello World!" 10 times with "sleep" for a second, then the program should print "Hello Moon!" 10 times with "sleep" for 0.2 seconds. This process must be repeated forever. The problem is that the program only prints "Hello World!" 10 times. I do not really understand how to get the next thread to run!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "wrapper.h"
#include <pthread.h>
#define MAX 10
void* HelloMoonFunction(void* tid){
long t_id;
t_id = (long)tid;
sleep(tid);
printf("%d. Hello Moon! \n", tid+1);
return NULL;
}
void* HelloWorldFunction(void* tid){
int value = (int) (intptr_t) tid;
sleep(value);
printf("%d. Hello World!\n", value + 1);
return NULL;
}
int main(int ac, char * argv){
pthread_t hej,moon;
while(1){
for (int a = 0; a < MAX; a++){
pthread_create(&hej, NULL, HelloWorldFunction, (void*)(intptr_t) a);
}
for (int b = 0; b < MAX; b++){
pthread_join(&hej, NULL);
}
for (int i = 0; i < MAX; i++){
pthread_create(&moon, NULL, HelloMoonFunction, (void*)(intptr_t) i);
}
for (int j = 0; j < MAX; j++){
pthread_join(moon, NULL);
}
}
pthread_exit(NULL);
return(0);
}
The most important issue in your code is that the 10 thread IDs are stored in the same variable so the 10 pthread_joins are all called for the last thread ID.
Secondly, the data passed to the thread functions is an integer encoded into a pointer. This is not guaranteed to go well. A more portable approach would be to save the argument and pass a pointer to the saved value. However, your approach does simplify the code, so I have kept it below. Just be warned.
The 0.2 seconds difference in sleep times that you would like in the HelloMoonFunction() cannot be accomplished with sleep (sleep for n seconds), but the Posix usleep (sleep for n microseconds) is probably available even though it is obsoleted by Posix.
A modified version doing what I understand you want to accomplish could be the following:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#define MAX 10
void* HelloMoonFunction(void* tid){
int value = (intptr_t)tid;
usleep(value*200000);
printf("%d. Hello Moon! \n", value+1);
return NULL;
}
void* HelloWorldFunction(void* tid){
int value = (intptr_t)tid;
usleep(value*1000000);
printf("%d. Hello World!\n", value + 1);
return NULL;
}
int main(void){
pthread_t hej[MAX], moon[MAX];
while(1){
for (int a = 0; a < MAX; a++){
pthread_create(&hej[a], NULL, HelloWorldFunction, (void *)(intptr_t)a);
}
for (int b = 0; b < MAX; b++){
pthread_join(hej[b], NULL);
}
for (int i = 0; i < MAX; i++){
pthread_create(&moon[i], NULL, HelloMoonFunction, (void *)(intptr_t)i);
}
for (int j = 0; j < MAX; j++){
pthread_join(moon[j], NULL);
}
}
return(0);
}
I am currently working on the calculation of the Eratosthenes Sieve using C multithreading.
The goal is to first create a main thread that uses a split function to divide the exploration of the numbers on a number of threads.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
void *creat_thread(int *nbThreads);
void *SieveEratosthenes(int *tailleTab);
int* tab;
int sizeTab;
int nbTachesParThread=0;
int main(void)
{
int nbThreads;
int n;
do{
printf("Enter an integer > 1 : ");
scanf("%d", &n);
} while(n<2);
sizeTab = n+1;
tab = (int*)malloc(tailleTab*sizeof(int));
for (unsigned int i=0; i<tailleTab; i++)
{
tab[i] = 1;
}
do{
printf("Enter a number positive number of threads : ");
scanf("%d", &nbThreads);
} while(nbThreads<1);
pthread_t threadPrincipal;
if (pthread_create(&threadPrincipal, NULL, creat_thread, NULL)) {
perror("pthread_create");
return EXIT_FAILURE;
}
if (pthread_join(threadPrincipal, NULL)) {
perror("pthread_join");
return EXIT_FAILURE;
}
printf("The Prime numbers are : \n");
for(unsigned int i=0; i<sizeTab; i++)
{
if(tab[i]==1)
{
printf("%d\n", (i));
}
}
}
void *creat_thread(int *nbThreads)
{
int nbTachesParThread = (int) sqrt(sizeTab) / nbThreads;
pthread_t* threads = (pthread_t*)malloc(nbThreads*sizeof(pthread_t));
int plageThreadi = nbTachesParThread;
for(int i = 0; i < nbThreads; ++i)
pthread_create (&threads[i], NULL, SieveEratosthenes, plageThreadi);
plageThreadi += nbTachesParThread;
}
void *SieveEratosthenes(int *plageThread)
{
for( int i=(plageThread - nbTachesParThread); i<=plageThread; i++)
{
if (tab[i] == 1)
{
for (int j = i*i; j<sizeTab; j += i)
{
tab[j]=0;
}
}
}
}
I tried to implement a code but I have an error at runtime:
segmentation error (core dumped)
On top of the issue mention in my comment here there is more to fix:
1st of all a PThread function needs to be of type void *(*)(void*). The ones used by the code are of type void *(*)(int*). Not good.
2ndly the code misses to join the work-threads, therefore the distributing thread ends after having created all workers, then it gets joined in main(), which then accesses the variables the workers are most likely are still working on causing undefined behaviour be doing so and then ends, ending the process. Ending the process cancels all worker-threads.
I followed your advice and created a structure to contain the variables that will be used by all threads.
However I noticed that sometimes it works (it displays the prime numbers well) but sometimes it doesn't work and it displays either only 0 or all the numbers from 0 to i.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
void *creat_thread(void* arg);
void *SieveEratosthenes(void* arg);
struct param
{
int* tab;
int sizeTab;
int nbTachesParThread;
int nbThreads;
int plageThreadi;
int plageThreadPrecedent;
};
int main(void)
{
struct param p;
int n;
do{
printf("Enter an integer > 1 : ");
scanf("%d", &n);
} while(n<2);
p.sizeTab = n+1;
p.tab = (int*)malloc(p.sizeTab*sizeof(int));
for (unsigned int i=0; i<p.sizeTab; i++)
{
p.tab[i] = 1;
}
do{
printf("Enter a number positive number of threads : ");
scanf("%d", &p.nbThreads);
} while(p.nbThreads<1);
pthread_t threadPrincipal;
if (pthread_create(&threadPrincipal, NULL, (void*)creat_thread, &p)) {
perror("pthread_create");
return EXIT_FAILURE;
}
if (pthread_join(threadPrincipal, NULL)) {
perror("pthread_join");
return EXIT_FAILURE;
}
printf("The Prime numbers are : \n");
for(unsigned int i=0; i<p.sizeTab; i++)
{
if(p.tab[i]==1)
{
printf("%d\n", i);
}
}
}
void *creat_thread(void* arg)
{
struct param *args = (void*)arg;
args->nbTachesParThread = (int) sqrt(args->sizeTab) / args->nbThreads;
pthread_t* threads = (pthread_t*)malloc(args->nbThreads*sizeof(pthread_t));
args->plageThreadi = args->nbTachesParThread;
for(int i = 0; i < args->nbThreads; ++i)
{
pthread_create (&threads[i], NULL, (void*)SieveEratosthenes, &(*args));
args->plageThreadPrecedent = args->plageThreadi;
args->plageThreadi += args->nbTachesParThread;
}
for(int i = 0; i < args->nbThreads; ++i)
{
pthread_join(threads[i], NULL);
}
pthread_exit(NULL);
}
void *SieveEratosthenes(void* arg)
{
struct param *args = (void *)arg;
for(int i=(args->plageThreadPrecedent); i<=args->plageThreadi; i++)
{
if (args->tab[i] == 1)
{
for (int j = i*i; j<args->sizeTab; j += i)
{
args->tab[j]=0;
}
}
}
pthread_exit(NULL);
}
In the main() function, move the calls to pthread_create() and pthread_join() outside of the if statement. These calls should be made regardless of whether or not the pthread_create() call succeeds.
In the SieveEratosthenes() function, the loop that marks composite numbers as 0 should start from i * i, not i. This is because any composite number can be written as the product of two prime numbers, and one of those prime numbers must be less than or equal to the square root of the composite number. Therefore, if a number i is composite, it must have a prime factor less than or equal to the square root of i.
In the creat_thread() function, move the call to pthread_join() inside the loop that creates the threads. This will ensure that each thread has completed before the next one is created.
In the creat_thread() function, initialize the plageThreadPrecedent variable to 2, since this is the first prime number.
I've modified my code so actually I have no more error code but once I have entered the 2 variables (number to calculate + number of threads), the program runs but displays nothing.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
void *creat_thread();
void *SieveEratosthenes();
int* tab;
int sizeTab = 0;
int nbTachesParThread=0;
int nbThreads = 0;
int plageThreadi = 0;
int plageThreadPrecedent = 0;
int main(void)
{
int n;
do{
printf("Enter an integer > 1 : ");
scanf("%d", &n);
} while(n<2);
sizeTab = n+1;
tab = (int*)malloc(sizeTab*sizeof(int));
for (unsigned int i=0; i<sizeTab; i++)
{
tab[i] = 1;
}
do{
printf("Enter a number positive number of threads : ");
scanf("%d", &nbThreads);
} while(nbThreads<1);
pthread_t threadPrincipal;
if (pthread_create(&threadPrincipal, NULL, creat_thread, NULL)) {
perror("pthread_create");
return EXIT_FAILURE;
}
if (pthread_join(threadPrincipal, NULL)) {
perror("pthread_join");
return EXIT_FAILURE;
}
printf("The Prime numbers are : \n");
for(unsigned int i=0; i<sizeTab; i++)
{
if(tab[i]==1)
{
printf("%d\n", (i));
}
}
}
void *creat_thread()
{
int nbTachesParThread = (int) sqrt(sizeTab) / nbThreads;
pthread_t* threads = (pthread_t*)malloc(nbThreads*sizeof(pthread_t));
int plageThreadi = nbTachesParThread;
for(int i = 0; i < nbThreads; ++i)
{
pthread_create (&threads[i], NULL, SieveEratosthenes, NULL);
pthread_join(threads[i], NULL);
plageThreadPrecedent = plageThreadi;
plageThreadi += nbTachesParThread;
}
for(int i = 0; i < nbThreads; ++i)
{
pthread_join(threads[i], NULL);
}
pthread_exit(NULL);
}
void *SieveEratosthenes()
{
for(int i=(plageThreadPrecedent); i<=plageThreadi; i++)
{
if (tab[i] == 1)
{
for (int j = i*i; j<sizeTab; j += i)
{
tab[j]=0;
}
}
}
pthread_exit(NULL);
}
I was trying to write a program that calculates prime numbers using threads and the program was working but not giving the desired results (it was telling all numbers were prime numbers). Today I tried to run the program again and I'm getting a segmentation fault even though I didn't alter my program. I tried using gdb to find when it was happening and I think it's happening on the pthread_join function.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int n_threads; // number of threads
int* numbers; // array of numbers
int elements_per_thread;
int isPrime(int n){
int i = 0;
for(i=0; i < n; i++)
if(n%i == 0)
return 0;
return 1;
}
void * threadPrime(void * arg){
int* idxp = (int*)arg;
int idx = *idxp;
int start = idx* elements_per_thread;
int finish = (idx+1)*elements_per_thread-1;
int i;
for(i=start; i<finish; i++)
if(!isPrime(i))
numbers[i]=0;
pthread_exit(NULL);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("usage: %s largest_number number_threads\n", argv[0]);
return 1;
}
int largest_number = atoi(argv[1]); // value of the largest number to test for primality
int n_numbers = largest_number-1; // number of numbers to test
n_threads = atoi(argv[2]);
// create and fill vector of numbers to test
numbers = (int *)malloc(n_numbers*sizeof(int)) ; // allocate a vector for n_numbers integers
int i;
for (i = 2; i <= largest_number; i++)
numbers[i-2] = i;
int* id = (int *)malloc(n_threads*sizeof(int));
// compute primes
pthread_t* thid = (pthread_t *)malloc(n_threads*sizeof(int));
for(i=0;i<n_threads;i++){
id[i] = i;
if(pthread_create(&thid[i],NULL,threadPrime,(void*)(id+i)) != 0){
printf("Erro\n");
exit(0);
}
}
for(i=0;i<n_threads;i++){
if(pthread_join(thid[i],NULL) != 0){
printf("Erro\n");
exit(0);
}
}
// print result
printf("Primes:");
int n_primes = 0;
for (i = 0; i < n_numbers; i++)
if (numbers[i]) {
n_primes++;
printf (" %d", numbers[i]);
}
printf("\nTotal: %d primes\n", n_primes);
return 0;
}
Problem solved. Correct code below.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int n_threads; // number of threads
int* numbers; // array of numbers
int elements_per_thread;
int isPrime(int n){
int i = 0;
for(i=2; i < n; i++)
if(n%i == 0)
return 0;
return 1;
}
void * threadPrime(void * arg){
int* idxp = (int*) arg;
int idx = *idxp;
int start = idx*elements_per_thread;
int finish = (idx+1)*elements_per_thread;
int i;
for(i=start; i<=finish; i++)
if(!isPrime(numbers[i]))
numbers[i]=0;
pthread_exit(NULL);
}
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("usage: %s largest_number number_threads\n", argv[0]);
return 1;
}
int largest_number = atoi(argv[1]); // value of the largest number to test for primality
int n_numbers = largest_number-1; // number of numbers to test
n_threads = atoi(argv[2]);
// create and fill vector of numbers to test
numbers = (int *)malloc(n_numbers*sizeof(int)) ; // allocate a vector for n_numbers integers
int i;
for (i = 2; i <= largest_number; i++)
numbers[i-2] = i;
int* id;
id = (int *)malloc(n_threads*sizeof(int));
// compute primeselements_per_thread = n_numbers/n_threads;
elements_per_thread = (n_numbers/n_threads)+1;
pthread_t* thid = malloc(n_threads*sizeof(*thid));
for(i=0;i<n_threads;i++){
id[i] = i;
if(pthread_create(&thid[i],NULL,threadPrime,(void*)(id+i)) != 0){
printf("Erro\n");
exit(0);
}
}
for(i=0;i<n_threads;i++){
if(pthread_join(thid[i],NULL) != 0){
printf("Erro\n");
exit(0);
}
}
// print result
printf("Primes:");
int n_primes = 0;
for (i = 0; i < n_numbers; i++)
if (numbers[i]) {
n_primes++;
printf (" %d", numbers[i]);
}
printf("\nTotal: %d primes\n", n_primes);
return 0;
}
There are a number of issues:
1) The starting index for the loop should be 2. Otherwise, you are going to have divide by zero error here:
for(i=0; i < n; i++) // should be i=2
if(n%i == 0)
return 0;
2) elements_per_thread is not set at all. So it's going to be 0 (since it's a global variable) and the loops in thread function will never be called. Set it in main():
elements_per_thread = n_numbers/n_threads;
3) When you call isPrime() you are passing i. But you really wanted to pass numbers[i]. You also want to include the finish in the primality test. So it should be
for(i=start; i<=finish; i++)
if(!isPrime(numbers[i]))
numbers[i]=0;
4) The allocation for thread array is wrong. It should be
pthread_t* thid = malloc(n_threads * sizeof *thid);
There are more efficient ways to test primes (e.g. you only need to check upto n/2 to see if it's prime). But once you fix the above issues, you'll have a working code and think about improving it later.
You didn't allocate the right amount of memory for thid. This is the main reason for your segmentation fault.
pthread_t* thid = (pthread_t *)malloc(n_threads*sizeof(int));
should be
pthread_t* thid = malloc(n_threads*sizeof(p_thread));
(you don't need to cast malloc in C)
This is why I don't usually use an explicit type as the operand of sizeof, and instead just use the variable name so that the compiler can deduce the type itself.
pthread_t* thid = malloc(n_threads*sizeof(*thid));
I am trying to develop a program which has multithreading with priority by c in linux. So my code is below. When i run my program, i meet "Segmentation fault".I don't know what happend. Please help me.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void *max(void *);
void *avg(void *);
void *min(void *);
int tmp[5];
int main(int argc, char* argv[]){
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
pthread_setschedprio(thread1,2);
int i, j;
printf("Input number: \n");
for (j=0; j<5; j++) {
printf("tmp[%d]: ",j);
scanf("%d: ",&tmp[j]);
}
if ((i=pthread_create(&thread1, NULL, max, tmp)) != 0) {
printf("thread creation failed. %d\n", i);
}
if ((i=pthread_create(&thread2, NULL, avg, tmp)) != 0) {
printf("thread creation failed. %d\n", i);
}
if ((i=pthread_create(&thread3, NULL, min, tmp)) != 0) {
printf("thread creation failed. %d\n", i);
}
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
printf("Exiting main\n");
return 0;
}
void *max(void *arg){
int i;
int *arr = (int *)arg;
int max = arr[0];
for(i=1;i<5;i++){
if(max<arr[i]){
max = arr[i];
}
}
printf("Max of array is: %d\n", max);
sleep(1);
return NULL;
}
void *avg(void *arg){
int i;
int *arr = (int *)arg;
int sum =0;
float avg;
for(i=0;i<5;i++){
sum = sum + arr[i];
}
avg = sum/5.0;
printf("Average of array is: %f\n",avg);
sleep(1);
return NULL;
}
void *min(void *arg){
int i;
int *arr = (int *)arg;
int min = arr[0];
for(i=1;i<5;i++){
if(min>arr[i]){
min = arr[i];
}
}
printf("Min of array is: %d\n", min);
sleep(1);
return NULL;
}
You are calling pthread_setschedprio(thread1,2); when thread1 hasn't been initialized to a valid value. You can set the priority for a thread only after the thread has been created.
To be clear, you should indicate whether or not commenting out the call to pthread_setschedprio(thread1,2) enables the program to run without crashing. (Also - do you really want the colon in the scanf() format string?)
here:
scanf("%d: ",&tmp[j]);
may be this line creating problems, observe : after %d, I don't think so it is the place.
May be this is the reason.
I am trying to write a multi threaded program that takes a list of numbers from the command line and calculates various statistical values eg average, sum etc using separate worker threads. i have created three threads in this program and it compiles but i get errors. I am new to C and thread programming, please guide me in passing data to the thread for calculations?
This is my code:
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#define NUM_THREAD 3
int average, min, max;
void *
doSomeThing(void *param)
{
//int *id_ptr, taskid;
int *argv = (int *) param;
sleep(1);
//id_ptr=(int *) threadid;
//taskid= *id_ptr;
int j;
int sum = 0;
int upper = atoi(param);
sleep(1);
pthread_t id = pthread_self();
unsigned long i = 0;
if (id = 1) {
int i;
for (i = 0; i < upper; i++) {
sum += argv[i];
}
printf("sum of no's is :\n", sum);
}
if (id = 2) {
printf("\n Second thread processing\n");
}
if (id = 3) {
printf("\n Third thread processing\n");
}
for (i = 0; i < -1; i++);
{
pthread_exit(NULL);
}
}
int
main(int argc, char *argv[])
{
pthread_t threads[NUM_THREAD];
pthread_attr_t attr;
int *taskid[NUM_THREAD];
int i = 0;
int t;
int err;
//int input,a;
if (argc != 2) {
fprintf(stderr, "usage: a.out <integer value>\n");
return -1;
}
/*
printf("how many no's do u want to evaluate?:\n");
scanf("%d", &input);
printf("Enter the no's:\n");
for (a = 0; a < input; a++) {
arr[a] = (int) malloc(sizeof(int));
scanf("%d", &arr[a]);
printf("data:", &arr[a]);
}
*/
pthread_attr_init(&attr);
for (t = 0; t < NUM_THREAD; t++) {
taskid[t] = (int *) malloc(sizeof(int));
*taskid[t] = t;
printf("In main: creating thread %d\n", t);
err = pthread_create(&threads[t], &attr, doSomeThing, argv[1]);
if (err) {
printf("Error; return code from pthread_create() is %d\n",
err);
exit(-1);
}
}
for (t = 0; t < NUM_THREAD; t++) {
pthread_join(threads[t], NULL);
printf("Joining thread %d\n", t);
}
pthread_exit(NULL);
}
What makes you think pthread_create assigns a nice little number like 1, 2, 3 as a thread_id? When you call pthread_self(), it is unlikely that you will get 1, 2, or 3. Also you should eventually free the memory you obtained from malloc.
My suggestion is that you write a separate function for average, max, and min and call pthread_create explicitly 3 times passing in the 3 separate functions instead of using one function to do all.