segmentation fault: 11 Seems unusual - c

Please help me find this " segmentation fault:11 ". argv input looking fine. By the way this a dining philosopher problem. It was working hour ago but on minix machine but now on Unix machine it doesn't run. Please help me with the stupid error.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#define N 5
#define REPETITIONS 10
#define EATTIME 3000000
#define THINKTIME EATTIME * 3
#define LEFT (i+N-1)%N
#define RIGHT (i+1)%N
#define HUNGRY 1
#define EATING 2
#define THINKING 0
#define mutex "mutex"
#define mutexLock "mutex.lock"
#define Output "output"
#define states "states"
#define statesLock "states.lock"
#define binarySemaphore "semaphore"
#define binarySemaphoreLock "semaphore.lock"
#define up(lock) unlink(lock)
#define down(lock1,lock2) while(link(lock1,lock2)== -1);
void readFile(int numberFromFile[],char *file); /* declaring readfile() */
void writeFile(int numberToFile[],char *file); /* declaring writeFile() */
void setPhilosopher(int i,int number); /* declaring setPhilosopher() */
void take_Forks(int i); /* declaring take_Forks() */
void downPhilosopher(int i); /* declaring downPhilosopher() */
void thinking(int j); /* declaring thinking() */
void setState(int i,int number); /* declaring setState() */
void test(int i); /* declaring test() */
void philosopher(int i); /* declaring philosopher() */
void eating(int j); /* declaring eating() */
void put_Forks(int i); /* declaring put_Forks() */
int argNo(char *argv); /* declaring arg number() */
int main(int args,char *argv[])
{
int i; /* declaring i*/
i = argNo(argv[1]); /* assigning argument number to i*/
if((i < 0) || (i >= N))
{
fprintf(stderr,"Input not valid\n"); /* displays an error message*/
/* when number is less than 0*/
/* number is more than N */
}
else
{
if((i < N) && (i >= 0)) /* else calls the philosopher function*/
philosopher(i); /* and passes the number to it */
// printf("Hello %d\n", i);
}
}
int argNo(char *argv)
{
int number; /* declaring number*/
sscanf(argv,"%d",&number); /* gets number from the command line */
return number; /* return number*/
}
void philosopher(int i)
{
int j; /* declaring j*/
for(j = 0; j < REPETITIONS; j++)
{
thinking(i); /* invoking thinking function*/
take_Forks(i); /* invoking take_Forks function*/
eating(i); /* invoking eating function*/
put_Forks(i); /* invoking put_Forks function*/
}
}
void thinking(int j)
{
int i,pid; /* declaring i and pid */
FILE *fp = fopen(Output,"a+"); /* creating and opening a file*/
pid = getpid(); /* getting process id*/
for(i = 0;i < THINKTIME ; i++); /* philosopher is thinking */
fclose(fp); /* closing the file*/
}
void take_Forks(int i)
{
down(mutex,mutexLock); /* entering critical region*/
setState(i,HUNGRY); /* setting State to hungry */
test(i); /* invoking test function*/
up(mutexLock); /* exit critical region*/
downPhilosopher(i); /* invoking downPhilosopher function*/
}
void eating(int j)
{
int i; /* declaring i as an int */
int pid = getpid(); /* getting the process ID */
FILE *fp = fopen(Output,"a+"); /* creating and opening file */
fprintf(fp,"%d %d eating\n",pid,j); /* writing a message to a file*/
fprintf(stdout,"%d %d eating\n",pid,j); /* displaying to stdout*/
fflush(fp); /* flushing file*/
for(i = 0; i < EATTIME; i++); /* philosopher eating*/
fprintf(fp,"%d %d done eating\n",pid,j); /* writing message to file*/
fprintf(stdout,"%d %d done eating\n",pid,j); /* displaying to stdout*/
fflush(fp); /* flushing file*/
fclose(fp); /* closing file*/
}
void put_Forks(int i)
{
down(mutex,mutexLock); /* entering critical region*/
setState(i,THINKING); /* setting state to thinking */
test(LEFT); /* checks if left and right */
test(RIGHT); /* philosophers want to eat */
up(mutexLock); /* exit critical region*/
}
void downPhilosopher(int i)
{
int semaphores[N]; /* declaring semaphore array*/
do
{
readFile(semaphores,binarySemaphore); /* reading binarySemaphore into semaphore */
}while(semaphores[i] == 0); /* spin locks if semaphore is 0 */
setPhilosopher(i,0); /* setting the philosopher's state to 0*/
}
void setState(int i,int number)
{
int theStates[N]; /* declaring States array*/
down(states,statesLock); /* enters critical region*/
readFile(theStates,states); /* read states from file*/
theStates[i] = number; /* changing the state */
writeFile(theStates,states); /* writes a state to a file*/
up(statesLock); /* exit critical region*/
}
void test(int i)
{
int theStates[N]; /* declaring theStates array*/
down(states,statesLock); /* enters critical region*/
readFile(theStates,states); /* read file states*/
up(statesLock); /* exit critical region*/
if(theStates[i] == HUNGRY && theStates[LEFT] != EATING &&
theStates[RIGHT] != EATING)
{
setState(i,EATING); /* set the state of philosopher to eating*/
setPhilosopher(i,1); /* set the semaphore to 1*/
}
}
void setPhilosopher(int i,int number)
{
int semaphores[N]; /* declaring semaphores[]*/
down(binarySemaphore,binarySemaphoreLock); /* enters critical region*/
readFile(semaphores,binarySemaphore); /* reading from file*/
semaphores[i] = number; /* updates the semaphore array*/
writeFile(semaphores,binarySemaphore); /* writing semaphore to file*/
up(binarySemaphoreLock); /* exit critical region*/
}
void readFile(int numberFromFile[],char *file)
{
FILE *fp = fopen(file,"r"); /* creating and opening file*/
int i; /* declaring i as int */
for(i = 0; i< N; i++)
fscanf(fp,"%d",&numberFromFile[i]); /* reading from file into*/
/* numberFromFile array*/
fclose(fp); /* closing the file*/
}
void writeFile(int numberToFile[],char *file)
{
FILE *fp = fopen(file,"w"); /* creating and opening a file */
int i; /* declaring i as int */
for(i = 0; i< N; i++)
fprintf(fp,"%d\n",numberToFile[i]); /* writing */
/* numberToFile array to file*/
fclose(fp); /* closing the file*/
}

Your logic here doesn't validate the input completely:
i = argNo(argv[1]);
I can replicate a segfault if i provide no parameter where your code is expecting a number as the first argument on the command line.
A quick fix may be to check the size of argc (or "args" in your code) before trying to reference argv[1] (which may not have been supplied).

or try to run under gdb
$ gcc -g myprogram.c
(gdb) run
Starting program: /home/b3h3m0th/a.out
Program received signal SIGSEGV, Segmentation fault.
rawmemchr () at ../sysdeps/i386/rawmemchr.S:116
116 ../sysdeps/i386/rawmemchr.S: No such file or directory
try to search a bug report about that.

At this place the comment does not match the code:
void readFile(int numberFromFile[],char *file)
{
/* FILE *fp = fopen(file,"r"); /* creating and opening file*/
FILE *fp = fopen(file,"w+"); /* creating and opening file*/
A few notes:
it is a good habit to have preprocessor macros in ALLCAPS, this makes them easy to recognise
(global) constants with 1 letter names (N) are hard to search
always parenthesize macro arguments (LEFT,RIGHT)
never make macros refer to variable names,(LEFT,RIGHT)
(maybe) except for some trivial stuff (stderr, logfiles, global variables)
(I sinned to this rule, using the filo_count variable in the macros ;-)
Changed the mode for fopen to "w+",
Plus a few changes to main (added fork() ), plus removed lots of silly comments.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#define MAX_PHILOSOPHER 50
#define REPETITIONS 1
#define EATTIME 3000000
#define THINKTIME (EATTIME * 3)
#define LEFT(i) (((i)+filo_count-1)%filo_count)
#define RIGHT(i) (((i)+1)%filo_count)
#define HUNGRY 1
#define EATING 2
#define THINKING 0
#define MUTEX_FILENAME "mutex"
#define MUTEX_FILE_LOCK "mutex.lock"
#define LOG_FILENAME "output"
#define STATE_FILENAME "states"
#define STATE_FILE_LOCK "states.lock"
#define SEMAPHORE_FILENAME "semaphore"
#define SEMAPHORE_FILE_LOCK "semaphore.lock"
#define up(lock) unlink(lock)
#define down(file,lock) do {;} while(link(file,lock)== -1)
void readFile(int array[],char *file);
void writeFile(int array[],char *file);
void setPhilosopher(int i,int number);
void take_Forks(int i);
void downPhilosopher(int i);
void thinking(int j);
void setState(int i,int number);
void test(int i);
void philosopher(int i);
void eating(int j);
void put_Forks(int i);
int argNo(char *argv);
unsigned filo_count=0;
int main(int argc,char *argv[])
{
int i;
fprintf(stderr,"argc was %d\n", argc);
i = argv[1] ? argNo(argv[1]): -1;
if (i < 0 || i >= MAX_PHILOSOPHER)
{
fprintf(stderr,"Input not valid\n");
exit (1);
}
filo_count=i;
if (0) {
FILE *fp;
fp = fopen(MUTEX_FILENAME, "w"); fclose(fp);
fp = fopen(STATE_FILENAME, "w"); fclose(fp);
fp = fopen(SEMAPHORE_FILENAME, "w"); fclose(fp);
}
for(i=0; i < filo_count ; i++ ) {
if (fork()) continue;
/* philosopher is a child process */
philosopher(i);
break;
}
fprintf(stderr,"%d Dead.\n", getpid() );
return 0;
}
int argNo(char *argv)
{
int number;
sscanf(argv,"%d",&number);
return number;
}
void philosopher(int i)
{
int j;
for(j = 0; j < REPETITIONS; j++)
{
thinking(i);
take_Forks(i);
eating(i);
put_Forks(i);
}
}
void thinking(int j)
{
int i,pid;
FILE *fp = fopen(LOG_FILENAME,"a+");
for(i = 0;i < THINKTIME ; i++); /* burn some CPU */
fclose(fp);
}
void take_Forks(int i)
{
down(MUTEX_FILENAME,MUTEX_FILE_LOCK); /* enter critical region*/
setState(i,HUNGRY);
test(i);
up(MUTEX_FILE_LOCK);
downPhilosopher(i);
}
void eating(int j)
{
int i;
int pid = getpid();
FILE *fp = fopen(LOG_FILENAME,"a+");
fprintf(fp,"%d %d eating\n",pid,j);
fprintf(stdout,"%d %d eating\n",pid,j);
fflush(fp);
for(i = 0; i < EATTIME; i++); /* Spin idle while eating */
fprintf(fp,"%d %d done eating\n",pid,j);
fprintf(stdout,"%d %d done eating\n",pid,j);
fclose(fp);
}
void put_Forks(int i)
{
down(MUTEX_FILENAME,MUTEX_FILE_LOCK); /* enter critical region*/
setState(i,THINKING);
test(LEFT(i)); /* checks if left and right */
test(RIGHT(i)); /* philosophers want to eat */
up(MUTEX_FILE_LOCK);
}
void downPhilosopher(int i)
{
int semaphores[MAX_PHILOSOPHER];
do
{
readFile(semaphores,SEMAPHORE_FILENAME);
} while (semaphores[i] == 0); /* spin locks if semaphore is 0 */
setPhilosopher(i,0);
}
void setState(int i,int number)
{
int theStates[MAX_PHILOSOPHER];
down(STATE_FILENAME,STATE_FILE_LOCK); /* enters critical region*/
readFile(theStates,STATE_FILENAME);
theStates[i] = number;
writeFile(theStates,STATE_FILENAME); /* writes a state to a file*/
up(STATE_FILE_LOCK);
}
void test(int i)
{
int theStates[MAX_PHILOSOPHER];
down(STATE_FILENAME,STATE_FILE_LOCK); /* enters critical region*/
readFile(theStates,STATE_FILENAME);
up(STATE_FILE_LOCK);
if(theStates[i] == HUNGRY
&& theStates[LEFT(i)] != EATING
&& theStates[RIGHT(i)] != EATING)
{
setState(i,EATING);
setPhilosopher(i,1);
}
}
void setPhilosopher(int i,int number)
{
int semaphores[MAX_PHILOSOPHER];
down(SEMAPHORE_FILENAME,SEMAPHORE_FILE_LOCK); /* enter critical region*/
readFile(semaphores,SEMAPHORE_FILENAME);
semaphores[i] = number;
writeFile(semaphores,SEMAPHORE_FILENAME);
up(SEMAPHORE_FILE_LOCK);
}
void readFile(int array[],char *file)
{
FILE *fp = fopen(file,"w+"); /* creating and opening file*/
int i;
for(i = 0; i< filo_count; i++) {
if ( 1 > fscanf(fp,"%d",&array[i]) ) array[i] = -1;
}
fclose(fp);
}
void writeFile(int array[],char *file)
{
FILE *fp = fopen(file,"w"); /* creating and opening a file */
int i;
for(i = 0; i< filo_count; i++) {
fprintf(fp,"%d\n",array[i]);
}
fclose(fp);
}
I have not proven the above code correct, only that it works ;-)

Related

Printf with multiple threads (for real-time logging) in C

I have written a code for real-time logging. Here's the pseudo-code:
initialize Q; //buffer structure stores values to be printed
log(input)
{
push input to Q;
}
printLog() //infinte loop
{
loop(1)
{
if(Q is not empty)
{
values = pop(Q);
msg = string(values); //formating values into a message string
print(msg);
}
}
}
mainFunction()
{
loop(1)
{
/*
insert operations to be performed
*/
log(values); //log function called
}
}
main()
{
Create 4 threads; //1 mainFunction and 3 printLog
Bind them to CPUs;
}
I'm using atomic operations instead of locks.
When I print the output to the console, I see that each thread prints consecutively for a while. This must mean that once a thread enters printLog(), the other threads are inactive for a while.
What I want instead is while one thread is printing, another thread formats the next value popped from Q and prints it right after. How can this be achieved?
EDIT: I've realized the above information isn't sufficient. Here are some other details.
Buffer structure Q is a circular array of fixed size.
Pushing information to Q is faster than popping+printing. So by the time the Buffer structure is full, I want most of the information to be printed.
NOTE: mainFunction thread shouldn't wait to fill Buffer when it is full.
I'm trying to utilize all the threads at a given time. Currently, after one thread prints, the same thread reads and prints the next value (this means the other 2 threads are inactive).
Here's the actual code:
//use gcc main.c -o run -pthread
#define _GNU_SOURCE
#include <unistd.h>
#include <stdint.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <math.h>
#include <signal.h>
#include <stdlib.h>
#define N 3
/* Buffer size */
#define BUFFER_SIZE 1000
struct values
{
uint64_t num;
char msg[20];
};
struct values Q[BUFFER_SIZE];
int readID = -1;
int writeID = -1;
int currCount = 0;
void Log(uint64_t n, char* m)
{
int i;
if (__sync_fetch_and_add(&currCount,1) < BUFFER_SIZE)
{
i = __sync_fetch_and_add(&writeID,1);
i = i%BUFFER_SIZE;
Q[i].num = n;
strcpy(Q[i].msg, m);
}
else __sync_fetch_and_add(&currCount,-1);
}
void *printLog(void *x)
{
int thID = *((int*)(x));
int i;
while(1)
{
if(__sync_fetch_and_add(&currCount,-1)>=0)
{
i = __sync_fetch_and_add(&readID,1);
i = i%BUFFER_SIZE;
printf("ThreadID: %2d, count: %10d, message: %15s\n",thID,Q[i].num,Q[i].msg);
}
else __sync_fetch_and_add(&currCount,1);
}
}
void *mainFunction()
{
uint64_t i = 0;
while(1)
{
Log(i,"Custom Message");
i++;
usleep(50);
}
}
int main()
{
/* Set main() Thread CPU */
cpu_set_t cpusetMain;
CPU_ZERO(&cpusetMain);
CPU_SET(0, &cpusetMain);
if(0 != pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpusetMain))
printf("pthread_setaffinity_np failed for CPU: 0\n");
int LogThID[N+1];
pthread_t LogThreads[N+1];
/* Create Threads */
if (pthread_create(&LogThreads[0], NULL, &mainFunction, NULL) != 0){return 0;}
for(int i=1; i<N+1 ; i++)
{
LogThID[i] = i;
if (pthread_create(&LogThreads[i], NULL, &printLog, &LogThID[i]) != 0){return i;}
}
/* Set CPUs */
cpu_set_t cpuset[N+1];
for(int i=0; i<N+1; i++)
{
CPU_ZERO(&cpuset[i]);
CPU_SET(i+1, &cpuset[i]);
if(0 != pthread_setaffinity_np(LogThreads[i], sizeof(cpu_set_t), &cpuset[i]))
printf("pthread_setaffinity_np failed for CPU: %d\n", i+1);
}
struct sched_param param[N+1];
for(int i=0; i<N+1; i++)
{
param[i].sched_priority = 91;
if(0 != pthread_setschedparam(LogThreads[i],SCHED_FIFO,&param[i]))
printf("pthread_setschedparam failed for CPU: %d\n", i);
}
/* Join threads */
for(int i=0; i<N+1; i++)
{
pthread_join(LogThreads[i], NULL);
}
return 0;
}

Dont'tknow why this problem happening and Cant Figure this out solution.can anyone solve this?

This is an example code of produce consumer problems.
In Line 58,86,116,166,194 In function ‘void* Producer1(void*)’error: cast from ‘void*’ to ‘int’ loses precision [-fpermissive].
still don't know why this error happening and can't figure out its solution.
I Use Ubuntu as an operating system and g++ -pthread library function to solve this.
code is here:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include<semaphore.h>
//#include </usr/include/semaphore.h>
// for sleep
#include <unistd.h>
#define BUFF_SIZE 5 /* total number of slots */
typedef struct //Producing queue
{
char buf1[BUFF_SIZE]; /* shared var */
int in1; /* buf[in%BUFF_SIZE] is the first empty slot */
int out1; /* buf[out%BUFF_SIZE] is the first full slot */
sem_t full; /* keep track of the number of full spots */
sem_t empty; /* keep track of the number of empty spots */
// use correct type here
pthread_mutex_t mutex; /* enforce mutual exclusion to shared data */
} sbuf_t1;
typedef struct //Chokolate Cake queue
{
char buf2[BUFF_SIZE]; /* shared var */
int in2; /* buf[in%BUFF_SIZE] is the first empty slot */
int out2; /* buf[out%BUFF_SIZE] is the first full slot */
sem_t full; /* keep track of the number of full spots */
sem_t empty; /* keep track of the number of empty spots */
// use correct type here
pthread_mutex_t mutex; /* enforce mutual exclusion to shared data */
} sbuf_t2;
typedef struct //Vanilla Cake queue
{
char buf3[BUFF_SIZE]; /* shared var */
int in3; /* buf[in%BUFF_SIZE] is the first empty slot */
int out3; /* buf[out%BUFF_SIZE] is the first full slot */
sem_t full; /* keep track of the number of full spots */
sem_t empty; /* keep track of the number of empty spots */
// use correct type here
pthread_mutex_t mutex; /* enforce mutual exclusion to shared data */
} sbuf_t3;
sbuf_t1 shared1;
sbuf_t2 shared2;
sbuf_t3 shared3;
void *Producer1(void *arg)
{
int i, index;
char item;
index = (int)arg;
for(i=0; i<10; ++i)
{
sem_wait(&shared1.empty); //down called in this line
pthread_mutex_lock(&shared1.mutex); //acquired mutex lock now it can produced no contex will be switched
sleep(1);
shared1.buf1[shared1.in1] = 'C'; //item pusch in buffer like item[in] = item;
shared1.in1 = (shared1.in1+1)%BUFF_SIZE; //queue operation q = (in + 1) % buff_size
printf("[P%d] Producing Chokolate Cake...\n", index);
fflush(stdout);
/* Release the buffer */
pthread_mutex_unlock(&shared1.mutex); // unclock the mutex
/* Increment the number of full slots */
sem_post(&shared1.full); //buffer is full
//if (i % 2 == 1) sleep(1);
}
return NULL;
}
void *Producer2(void *arg)
{
int i, index;
char item;
index = (int)arg;
for(i=0; i<10; ++i)
{
item = i;
sem_wait(&shared1.empty);
pthread_mutex_lock(&shared1.mutex);
sleep(1);
shared1.buf1[shared1.in1] = 'V';
shared1.in1 = (shared1.in1+1)%BUFF_SIZE;
printf("[P%d] Producing Vanilla Cake...\n", index);
fflush(stdout);
/* Release the buffer */
pthread_mutex_unlock(&shared1.mutex);
/* Increment the number of full slots */
sem_post(&shared1.full);
//if (i % 2 == 1) sleep(1);
}
return NULL;
}
void *Chef_Z(void *arg)
{
int i, index;
char item;
index = (int)arg;
for (i=10; i > 0; i--) {
sem_wait(&shared1.full);
pthread_mutex_lock(&shared1.mutex);
sleep(1);
item=shared1.buf1[shared1.out1];
if(item == 'C') // Chokolate Cake queue
{
sem_wait(&shared2.full);
pthread_mutex_lock(&shared2.mutex);
shared2.buf2[shared2.in2]=item;
shared2.in2 = (shared2.in2+1)%BUFF_SIZE;
printf("[C_Z] Consuming Chokolate Cake and stored it in Chokolate queue ...\n");
pthread_mutex_unlock(&shared2.mutex);
/* Increment the number of full slots */
sem_post(&shared2.empty);
}
else if(item == 'V') // Vanilla Cake queue
{
sem_wait(&shared3.full);
pthread_mutex_lock(&shared3.mutex);
shared3.buf3[shared3.in3]=item;
shared3.in3 = (shared3.in3+1)%BUFF_SIZE;
printf("[C_Z] Consuming Vanilla Cake and stored it in Vanilla queue ...\n");
pthread_mutex_unlock(&shared3.mutex);
/* Increment the number of full slots */
sem_post(&shared3.empty);
}
shared1.out1 = (shared1.out1+1)%BUFF_SIZE;
fflush(stdout);
/* Release the buffer */
pthread_mutex_unlock(&shared1.mutex);
/* Increment the number of full slots */
sem_post(&shared1.empty);
/* Interleave producer and consumer execution */
//if (i % 2 == 1) sleep(1);
}
return NULL;
}
void *Waiter1(void *arg) //Chokolate cake waiter
{
int i, index;
char item;
index = (int)arg;
for (i=10; i > 0; i--) {
sem_wait(&shared2.full);
pthread_mutex_lock(&shared2.mutex);
sleep(1);
item=shared2.buf2[shared2.out2];
shared2.out2 = (shared2.out2+1)%BUFF_SIZE;
printf("[W%d] Consuming Chokolate Cake ...\n", index);
fflush(stdout);
/* Release the buffer */
pthread_mutex_unlock(&shared2.mutex);
/* Increment the number of full slots */
sem_post(&shared2.empty);
/* Interleave producer and consumer execution */
//if (i % 2 == 1) sleep(1);
}
return NULL;
}
void *Waiter2(void *arg) // Vanilla cake waiter
{
int i, index;
char item;
index = (int)arg;
for (i=10; i > 0; i--) {
sem_wait(&shared3.full);
pthread_mutex_lock(&shared3.mutex);
sleep(1);
item=shared3.buf3[shared3.out3];
shared3.out3 = (shared3.out3+1)%BUFF_SIZE;
printf("[W%d] Consuming Vanilla Cake ...\n", index);
fflush(stdout);
/* Release the buffer */
pthread_mutex_unlock(&shared3.mutex);
/* Increment the number of full slots */
sem_post(&shared3.empty);
/* Interleave producer and consumer execution */
//if (i % 2 == 1) sleep(1);
}
return NULL;
}
int main()
{
//pthread_t idP, idC;
pthread_t thread1,thread2,thread3,thread4,thread5;
int index;
void *producer1End;
void *producer2End;
void *chef_zEnd;
void *waiter1End;
void *waiter2End;
sem_init(&shared1.full, 0, 0);
sem_init(&shared1.empty, 0, BUFF_SIZE);
pthread_mutex_init(&shared1.mutex, NULL);
sem_init(&shared2.full, 0, 0);
sem_init(&shared2.empty, 0, BUFF_SIZE);
pthread_mutex_init(&shared2.mutex, NULL);
sem_init(&shared3.full, 0, 0);
sem_init(&shared3.empty, 0, BUFF_SIZE);
pthread_mutex_init(&shared3.mutex, NULL);
pthread_create(&thread1, NULL, Producer1, (void*)1 );
pthread_create(&thread2, NULL, Producer2, (void*)2 );
pthread_create(&thread3, NULL, Chef_Z, (void*)1 );
pthread_create(&thread4, NULL, Waiter1, (void*)1);
pthread_create(&thread5, NULL, Waiter2, (void*)2);
pthread_join(thread1,&producer1End);
pthread_join(thread2,&producer2End);
pthread_join(thread3,&chef_zEnd);
pthread_join(thread4,&waiter1End);
pthread_join(thread5,&waiter2End);
pthread_exit(NULL);
}

Message queues: Bad file descriptor in notification

I've created a table of mq file descriptors and I'm trying to pass numbers from stdin by one of them.
I'm using notification using threads and when a number occures in one of the queues it should print for example "Number: 1 from queue: 3".
Here's my code:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <mqueue.h>
#define MAX_LENGTH 20
#define ERR(source) (\
fprintf(stderr, "%s:%d\n", __FILE__, __LINE__),\
perror(source),\
kill(0, SIGKILL),\
exit(EXIT_FAILURE)\
)
static void not_func(union sigval sv) {
mqd_t queue;
uint8_t number;
unsigned msg_prio;
queue = *((mqd_t*)sv.sival_ptr);
static struct sigevent not;
not.sigev_notify = SIGEV_THREAD;
not.sigev_notify_function = not_func;
not.sigev_value.sival_ptr = &queue;
if(mq_notify(queue, &not)<0) ERR("mq_notify");
for(;;) {
if(mq_receive(queue, (char*)&number, 1, &msg_prio)<1) {
if(errno == EAGAIN) break;
else ERR("mq_receive");
printf("Number: %d from queue: %d", number, msg_prio);
}
}
}
void get_queue_name(int nr, char *str) {
snprintf(str, MAX_LENGTH, "/queue%d", nr);
}
mqd_t create_message_queue(int nr) {
mqd_t queue;
char name[MAX_LENGTH] = "";
get_queue_name(nr, name);
struct mq_attr attr;
attr.mq_maxmsg = 10;
attr.mq_msgsize = 1;
if((queue = TEMP_FAILURE_RETRY(mq_open(name, O_RDWR|O_NONBLOCK|O_CREAT, 0600, &attr))) == (mqd_t)-1) ERR("mq open in");
static struct sigevent not;
not.sigev_notify = SIGEV_THREAD;
not.sigev_notify_function = not_func;
not.sigev_value.sival_ptr = &queue;
if(mq_notify(queue, &not)<0) ERR("mq_notify");
return queue;
}
void delete_message_queue(mqd_t queue, int nr) {
char name[MAX_LENGTH] = "";
get_queue_name(nr, name);
mq_close(queue);
if(mq_unlink(name)) ERR("mq_unlink");
}
void usage(void) {
fprintf(stderr, "USAGE: mqueue n\n");
fprintf(stderr, "100 > n > 0 - number of children\n");
exit(EXIT_FAILURE);
}
int main(int argc, char **argv) {
int n, i;
char strnumber[MAX_LENGTH];
int number;
mqd_t *queues;
srand(time(NULL));
if(argc != 2) usage();
n = atoi(argv[1]);
if(n<=0 || n>=100) usage();
queues = (mqd_t*)malloc(sizeof(mqd_t) * n);
if(queues == NULL) ERR("malloc");
for(i = 0; i < n; i++) {
queues[i] = create_message_queue(i+1);
}
while(fgets(strnumber, MAX_LENGTH, stdin)!=NULL) {
number = (uint8_t)atoi(strnumber);
if(number<=0) continue;
int randomQueue = rand()%n;
if(TEMP_FAILURE_RETRY(mq_send(queues[randomQueue], (const char *)&number, 1, (unsigned)randomQueue))) ERR("mq_send");
}
for(i = 0; i < n; i++) {
delete_message_queue(queues[i], i+1);
}
free(queues);
return EXIT_SUCCESS;
}
When I execute my code nothing happens:
or I have such an error:
You pass a pointer to queue (which is a local variable) to the thread (via not.sigev_value.sival_ptr) which runs after that variable goes out of scope. So it gets a dangling pointer.
Either pass the descriptor by value (if it fits in sigval; it should), or store it on the heap (with new/malloc) and pass that pointer.

Create a countdown timer in C and continue code flow

So i am programming in c processes , and i need to create a timer that when it passes a certain point in my code it activates for x seconds, and then after the countdown timer hits 0 it does something. But in the meantime the code after the timer, needs to continue do to is work, following the flow of the code.
So in resume what i want to achieve is a countdown timer in c that when activated it creates another process were it counts the time and do something after.
Sorry if i did not explained this well enough.
Thanks in advance.
My code is the following so far i want to put the timer in the middle of the consumeTutuc method.
#include "sema.h"
#include <sys/shm.h>
//#include <sys/types.h>
#define MAX_CHILD 3 /* max. # of child processes */
#define LIFETIME 5 /* max. lifetime of a process */
#define MAX_NTIME 4 /* max. time for normal work */
#define MAX_CTIME 2 /* max. time for critical work */
#define N 10
#define SHMKEY (key_t) 0x10
#define SHMKEY2 (key_t) 0x11
#define SHMKEY3 (key_t) 0x12
#define SHMKEY4 (key_t) 0x13
//estruturas
typedef struct
{
int numeroPessoas;
char condicao;
}PESSOAS;
typedef struct
{
int id;
int espera;
}TUTUC;
int in, out, inP, outP, tt;
int *ptr; /*posicao do tuctuc*/
int *ptr2; /*numero disponiveis de tuctuc*/
PESSOAS *ptr3; /*fila de pessoas*/
int *ptr4; /*pessoas a espera*/
semaphore mutex, empty, full, emptyP, fullP, mutexP;
void produceTucTuc();
void consumeTucTuc();
void producePessoas();
void consumePessoas();
int main (void)
{
//MEMORIA
int shmid;
int shmid2;
int shmid3;
int shmid4;
char *addr;
char *addr2;
char *addr3;
char *addr4;
shmid = shmget(SHMKEY, N, 0777|IPC_CREAT);
shmid2 = shmget(SHMKEY2, N, 0777|IPC_CREAT);
shmid3 = shmget(SHMKEY3, N, 0777|IPC_CREAT);
shmid4 = shmget(SHMKEY4, N, 0777|IPC_CREAT);
addr=(char*)shmat(shmid,0,0);
addr2=(char*)shmat(shmid2,0,0);
addr3=(char*)shmat(shmid3,0,0);
addr4=(char*)shmat(shmid4,0,0);
ptr=(int*)addr;
ptr2=(int*)addr2;
ptr3=(PESSOAS*)addr3;
ptr4=(int*)addr4;
//MEMORIA
tt=1;
in=0;
out=0;
inP=0;
outP=0;
*ptr=0;
*ptr2=1;
//SEMAFOROS
full = init_sem(0);
empty = init_sem(N);
mutex = init_sem(1);
fullP = init_sem(0);
emptyP = init_sem(N);
mutexP = init_sem(1);
semaphore s;
//SEMAFOROS
int child_pid [MAX_CHILD], /* process ID's */
wait_pid;
int i, j,i2, /* loop variables */
child_stat; /* return status of child */
srand (time(NULL));
s = init_sem (1); /* create sem with value 1 */
for(i=0; i<10; i++){
produceTucTuc();
}
for (i = 0; i < MAX_CHILD; ++i)
{
child_pid [i] = fork ();
switch (child_pid [i])
{
case -1: /* error: no process created */
perror ("fork failed");
exit (1);
break;
case 0: /* child process */
/* up to Linux 2.0.x the process didn't terminate after
* LIFETIME seconds because "alarm()" and "sleep()" have
* used the same clock. This problem is solved in Linux 2.2.x
*/
if(i==0) produceTucTuc();
//if(i==1) consumeTucTuc();
if(i==1) producePessoas();
if(i==2) consumePessoas();
break;
default: /* parent process */
if (i == (MAX_CHILD - 1)) /* all childs created ? */
{ /* yes -> wait for termination */
for (j = 0; j < MAX_CHILD; ++j)
{
wait_pid = wait (&child_stat);
if (wait_pid == -1)
{
perror ("wait failed");
};
};
printf ("All child processes have terminated.\n");
//LIBERTA MEMORIA
rel_sem (s);
rel_sem (mutex);
rel_sem (empty);
rel_sem (full);
rel_sem (mutexP);
rel_sem (emptyP);
rel_sem (fullP);
shmdt(addr);
shmctl(shmid, IPC_RMID,NULL);
shmdt(addr2);
shmctl(shmid2, IPC_RMID,NULL);
shmdt(addr3);
shmctl(shmid3, IPC_RMID,NULL);
shmdt(addr4);
shmctl(shmid4, IPC_RMID,NULL);
//LIBERTA MEMORIA
};
}; /* end switch */
}; /* end for */
return 0;
}
void produceTucTuc(){
int ntuctuc;
alarm(LIFETIME);
//for(;;){
P(empty);
P(mutex);
*(ptr+in)=tt;
ntuctuc=*ptr2;
printf("------------------------------------\n");
printf("Produzi na pos %d o tuctuc %d\n",in,tt);
printf("Numero de TucTucs disponiveis:%d\n",ntuctuc);
in=(in+1)%N;
ntuctuc++;
*ptr2=ntuctuc;
tt=(tt+1)%N;
V(mutex);
V(full);
//}
}
void consumeTucTuc(){
int tuctuc;
int ntuctuc;
alarm(LIFETIME);
P(full);
P(mutex);
tuctuc=*(ptr+out);
ntuctuc=*ptr2;
ntuctuc--;
//printf("------------------------------------\n");
printf("Consumi na pos %d o tuctuc %d\n",out,tuctuc);
printf("Numero de TucTucs disponiveis:%d\n",ntuctuc);
out=(out+1)%N;
*ptr2=ntuctuc;
V(mutex);
V(empty);
}
void producePessoas(){
PESSOAS pessoa;
int espera =0;
alarm(LIFETIME);
for(;;){
P(emptyP);
P(mutexP);
if(rand()%5 == 0){
pessoa.numeroPessoas = 5;
}
else {
pessoa.numeroPessoas=rand()%5;
}
if(rand()%10<3){
pessoa.condicao = 'E';
}
else {
pessoa.condicao = 'N';
}
*(ptr3+inP)=pessoa;
espera=*ptr4;
espera=espera+pessoa.numeroPessoas;
*ptr4=espera;
printf("------------------------------------\n");
printf("Na pos %d entraram %d pessoas com %c condicao\n",inP,pessoa.numeroPessoas, pessoa.condicao);
printf("Estao %d pessoas à espera\n",*ptr4);
inP=(inP+1)%N;
V(mutexP);
V(fullP);
}
}
void consumePessoas(){
int pessoa;
int espera;
int p;
int aux;
alarm(LIFETIME);
while((*(ptr3 + outP)).numeroPessoas<(*ptr2)){
P(fullP);
P(mutexP);
pessoa=(*(ptr3+outP)).numeroPessoas;
espera=*ptr4;
espera=espera-pessoa;
*ptr4=espera;
printf("------------------------------------\n");
printf("Na pos %d sairam %d pessoas\n",inP,pessoa);
printf("Estao %d pessoas à espera\n",espera);
if(pessoa%2==1){
aux=(pessoa/2) + 1;
}else{
aux=pessoa/2;
}
for(p=0; p<aux; p++){
printf("%d\n",pessoa);
consumeTucTuc();
}
outP=(outP+1)%N;
V(mutexP);
V(emptyP);
}
}
This function you can call as a thread an it's a counter:
(You can build in a condition in the while loop and kill the thread!)
void counter( void *dummy ){
time_t start;
int weiter = 1,count = 0;
while (weiter) {
time(&start);
printf("\b\b\b\b%3i:",count);
while(difftime(time(NULL),start)<1);
count++;
//if condition kill thread
}
}

Producer Consumer program using semaphores and pthreads

I have written a code for producer-consumer problem.But I am not getting the output.There is no compilation error,but warning in my program.I am confused.Trying very hard.But can't get it.Please tell me what is wrong in my program.What will be the correct program.I am getting frustrated.Please help guys.
Here is the code-
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/semaphore.h>
#define BUFF_SIZE 5 /* total number of slots */
#define NP 3 /* total number of producers */
#define NC 3 /* total number of consumers */
#define NITERS 4 /* number of items produced/consumed */
typedef struct {
int buf[BUFF_SIZE]; /* shared var */
int in; /* buf[in%BUFF_SIZE] is the first empty slot */
int out; /* buf[out%BUFF_SIZE] is the first full slot */
sem_t full; /* keep track of the number of full spots */
sem_t empty; /* keep track of the number of empty spots */
sem_t mutex; /* enforce mutual exclusion to shared data */
} sbuf_t;
sbuf_t shared;
void *Producer(void *arg) {
int i, item, index;
index = (int) arg;
for (i = 0; i < NITERS; i++) {
/* Produce item */
item = i;
/* Prepare to write item to buf */
/* If there are no empty slots, wait */
sem_wait(&shared.empty);
/* If another thread uses the buffer, wait */
sem_wait(&shared.mutex);
shared.buf[shared.in] = item;
shared.in = (shared.in+1)%BUFF_SIZE;
printf("[P%d] Producing %d ...\n", index, item); fflush(stdout);
/* Release the buffer */
sem_post(&shared.mutex);
/* Increment the number of full slots */
sem_post(&shared.full);
/* Interleave producer and consumer execution */
if (i % 2 == 1) sleep(1);
}
return NULL;
}
void *Consumer(void *arg) {
int i, item, index;
index = (int) arg;
for (i = NITERS; i > 0; i--) {
sem_wait(&shared.full);
sem_wait(&shared.mutex);
item = i;
item = shared.buf[shared.out];
shared.out = (shared.out + 1) % BUFF_SIZE;
printf("[C%d] Consuming %d ...\n", index, item); fflush(stdout);
/* Release the buffer */
sem_post(&shared.mutex);
/* Increment the number of full slots */
sem_post(&shared.empty);
/* Interleave producer and consumer execution */
if (i % 2 == 1) sleep(1);
}
return NULL;
}
int main() {
pthread_t idP, idC;
int index;
sem_init(&shared.full, 0, 0);
sem_init(&shared.empty, 0, BUFF_SIZE);
pthread_mutex_init(&shared.mutex, NULL);
for (index = 0; index < NP; index++) {
/* Create a new producer */
pthread_create(&idP, NULL, Producer, (void*)index);
}
/*create a new Consumer*/
for (index = 0;index < NC;index++) {
pthread_create(&idC, NULL, Consumer, (void*)index);
}
pthread_exit(NULL);
}
Maybe you should take the Compiler warnings more serious.
Incorrect types and undefined functions are usually shown
as warning...
I haven't checked the Logic of your program, but the principle should work:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include </usr/include/semaphore.h>
// for sleep
#include <unistd.h>
#define BUFF_SIZE 5 /* total number of slots */
#define NP 3 /* total number of producers */
#define NC 3 /* total number of consumers */
#define NITERS 4 /* number of items produced/consumed */
typedef struct
{
int buf[BUFF_SIZE]; /* shared var */
int in; /* buf[in%BUFF_SIZE] is the first empty slot */
int out; /* buf[out%BUFF_SIZE] is the first full slot */
sem_t full; /* keep track of the number of full spots */
sem_t empty; /* keep track of the number of empty spots */
// use correct type here
pthread_mutex_t mutex; /* enforce mutual exclusion to shared data */
} sbuf_t;
sbuf_t shared;
void *Producer(void *arg)
{
int i, item, index;
index = (int)arg;
for (i=0; i < NITERS; i++)
{
/* Produce item */
item = i;
/* Prepare to write item to buf */
/* If there are no empty slots, wait */
sem_wait(&shared.empty);
/* If another thread uses the buffer, wait */
pthread_mutex_lock(&shared.mutex);
shared.buf[shared.in] = item;
shared.in = (shared.in+1)%BUFF_SIZE;
printf("[P%d] Producing %d ...\n", index, item);
fflush(stdout);
/* Release the buffer */
pthread_mutex_unlock(&shared.mutex);
/* Increment the number of full slots */
sem_post(&shared.full);
/* Interleave producer and consumer execution */
if (i % 2 == 1) sleep(1);
}
return NULL;
}
void *Consumer(void *arg)
{
int i, item, index;
index = (int)arg;
for (i=NITERS; i > 0; i--) {
sem_wait(&shared.full);
pthread_mutex_lock(&shared.mutex);
item=i;
item=shared.buf[shared.out];
shared.out = (shared.out+1)%BUFF_SIZE;
printf("[C%d] Consuming %d ...\n", index, item);
fflush(stdout);
/* Release the buffer */
pthread_mutex_unlock(&shared.mutex);
/* Increment the number of full slots */
sem_post(&shared.empty);
/* Interleave producer and consumer execution */
if (i % 2 == 1) sleep(1);
}
return NULL;
}
int main()
{
pthread_t idP, idC;
int index;
sem_init(&shared.full, 0, 0);
sem_init(&shared.empty, 0, BUFF_SIZE);
pthread_mutex_init(&shared.mutex, NULL);
for (index = 0; index < NP; index++)
{
/* Create a new producer */
pthread_create(&idP, NULL, Producer, (void*)index);
}
/*create a new Consumer*/
for(index=0; index<NC; index++)
{
pthread_create(&idC, NULL, Consumer, (void*)index);
}
pthread_exit(NULL);
}
I hope this helps.
There are still compiler warnings. The correct way to get the integer value from a void pointer is:
index = *(int*)arg;
And, also to pass an integer pointer, is below:
pthread_create(&idC,NULL,Consumer,(void*)&index);
I still have some doubts as to how the Consumer or the Producer thread will receive the passed integer value since that is an address of the index variable in the for loop in the main thread. As soon as index gets incremented, the Consumer or Producer thread is affected by this increment.

Resources