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.
Related
I need help with my assignment. The assignment is about there is one producer and argv[1] number of consumers. Producer will produce a number from 1001 to 1010 and consumer will consume it. Everything is fine with the output of my code but the main issue is my code is not terminating. Can anyone help me with it.HELP IS NEEDED!! This is my code:-`
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#define MAXIMUM 5
#define lower_time 2
#define max_time 5
void *producer();
void *consumer();
sem_t empty;
sem_t full;
int in = 0;
int out = 0;
int buffer[MAXIMUM];
pthread_mutex_t mutex;
int main(int argc, char *argv[]) {
/* argv[1] is number of consumer thread*/
int n = atoi(argv[1]);
int a[n];
for(int i=0;i<n;i++) {
a[i]=(i+1);
}
for(int i=0;i<MAXIMUM;i++) {
buffer[i]=0;
}
pthread_t ptid;
pthread_t ctid[n];
pthread_mutex_init(&mutex, NULL);
sem_init(&empty,0,MAXIMUM);
sem_init(&full,0,0);
printf("NUmber of consumer thread :- %d\n",n);
printf("Number of producer thread will be 1\n");
int in = 0; //index at which producer will put the next data
int out = 0; // index from which the consumer will consume next data
//creation of producer thread
pthread_create(&ptid,NULL,(void*)producer,NULL);
for(int i=0;i<n;i++) {
pthread_create(&ctid[i],NULL,(void*)consumer,(void*)&a[i]);
}
for(int i=0;i<n;i++) {
pthread_join(ctid[i],NULL);
}
pthread_join(ptid,NULL);
sem_destroy(&empty);
sem_destroy(&full);
sleep(n);
exit(0);
}
void insert_item(int item) {
sem_wait(&empty);
pthread_mutex_lock(&mutex);
buffer[in] = item;
printf("Producer is writing :- Insert Item %d at %d\n",buffer[in],in);
printf("Buffer Contents:-");
for(int i=0;i<MAXIMUM;i++) {
printf("%d ",buffer[i]);
}
printf("\n");
in = (in+1)%MAXIMUM;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
void remove_item(int p){
sem_wait(&full);
pthread_mutex_lock(&mutex);
int item = buffer[out];
buffer[out]=0;
printf("Consumer %d: Remove Item %d from %d\n",p,item, out);
for(int i=0;i<MAXIMUM;i++) {
printf("%d ",buffer[i]);
}
printf("\n");
out = (out+1)%MAXIMUM;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
void *producer() {
for(int i=1001;i<=1010;i++){
insert_item(i);
int num = (rand() %
(max_time - lower_time + 1)) + lower_time;
sleep(num);
}
printf("----Producer exiting------");
pthread_exit(0);
}
void *consumer( void *cno) {
int p=*((int *)cno);
for(int i=0;i<10;i++) {
int num = (rand() %
(max_time - lower_time + 1)) + lower_time;
sleep(num);
remove_item(p);
}
pthread_exit(0);
}
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
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
}
int main()
{
pthread_t tid[2];
for (int i = 0; i < 2; i++)
pthread_create(&tid[i], 0, runner, &i);
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
For the above code I expect the output to be
line 0
line 1
But the output is actually
line 1
line 2
So what is wrong with this code? How did i get incremented? Do I have to pass structs to the runner function?
There's no guarantee that printf("line: %d\n", *line); line will finish before pthread_create returns, which means you have a race on i.
(The main thread tries to increment it and the new threads try to read it
via their argument pointer).
You can solve the problem by passing pointers to different objects (one per thread, optimally cache-aligned, but that hardly matters here):
#include <stdio.h>
#include <pthread.h>
void *runner(void * p)
{
int *line = p;
printf("line: %d\n", *line);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
ints[i]=i;
if(pthread_create(&tid[i], 0, runner, &ints[i])) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
or by passing the i by value (by casting it to void*):
#include <stdio.h>
#include <pthread.h>
#include <stdint.h>
void *runner(void * p)
{
printf("line: %d\n", (int)(intptr_t)p);
return 0;
}
int main()
{
pthread_t tid[2];
int ints[2];
for (int i = 0; i < 2; i++){
if(pthread_create(&tid[i], 0, runner, (void*)(intptr_t)i)) return 1;
}
for (int i = 0; i < 2; i++)
pthread_join(tid[i], NULL);
return 0;
}
I have got a project from my university for critical section problem of n processes. I have made a code for 2 processes in c But I could not figure out how to get it working for n process . The code is in C for linux threads.
Here is code for 2 Processes.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int flag[2];
int turn;
const int MAX = 1e9;
int ans = 0;
void lock_init(){
flag[0]=flag[1]=0;
turn = 0;
}
void lock(int self){
flag[self]=1;
turn = 1-self;
while(flag[1-self]==1 && turn == 1-self);
}
void unlock(int self){
flag[self]=0;
}
void* func(void *s){
int i=0;
int *limitptr = (int*) s;
int self = *limitptr;
printf("Thread %d in queue for critical section\n",self);
lock(self);
printf("Thread %d in critical section\n",self);
for(i=0;i<MAX;i++){
ans++;
}
printf("Thread %d done counting\n",self);
printf("Thread %d is exiting critical section\n",self);
unlock(self);
}
int main(){
pthread_t p1, p2;
int a=0,b=1;
lock_init();
pthread_create(&p1, NULL, func, &a);
pthread_create(&p2, NULL, func, &b);
pthread_join(p1, NULL);
pthread_join(p2, NULL);
printf("Exiting Main\n");
return 0;
}
Any help would be appreciated.
Thank You. :)
use a mutex
#include <pthread.h>
declare the mutex like so:
pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER;
then at the beginning of a critical section call:
pthread_mutex_lock( &myMutex );
and at the end of the critical section call:
pthread_mutex_unlock( &myMutex );
it does not matter how many threads are using that critical section, only one thread will be able to access it at a time
Thank You for your valuable time and answers.
I Found A solution for My problem and thought of sharing it.I Implemented Bakery Algorithm In C.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
int N;
int global = 10;
int entering[100];
int number[100];
int max(int number[100]) {
int i = 0;
int maximum = number[0];
for (i = 0; i < N; i++) {
if (maximum < number[i])
maximum = number[i];
}
return maximum;
}
void lock(int i) {
int j = 0;
entering[i] = TRUE;
number[i] = 1 + max(number);
entering[i] = FALSE;
for (j = 0; j < N; j++) {
while (entering[j]);
while (number[j] != 0 && (number[j] < number[i] || (number[i] == number[j]) && j < i)) {}
}
}
void unlock(int i) {
number[i] = 0;
}
void *fn(void *integer) {
int i = (int) integer;
lock(i);
printf("\n\n-----------Process %d---------",i);
printf("\nProcess %d is Entering Critical Section\n",i);
global++;
printf("%d is the value of global \n",global);
printf("Process %d is leaving Critical Section\n",i);
printf("----------------------------------\n\n");
unlock(i);
}
int main()
{
printf("Enter Number of Process\n");
scanf("%d",&N);
int th[N];
void *fn(void *);
pthread_t thread[N];
int i = 0;
for (i = 0; i < N; i++) {
th[i] = pthread_create(&thread[i], NULL, fn, (void *)i);
pthread_join(thread[i], NULL);
}
return EXIT_SUCCESS;
}
Again Thank You :)
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.