Buffer bounded problem using semaphores using C in Linux - c

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);
}

Related

Reusable barrier implementation using POSIX semaphores

Need a solution that creates 5 pthreads. Each pthread executes a function that involves iterating through a loop 10 times. In each iteration of the loop, a thread increments an int from 0 to 0.9*MAX_INT and then prints the iteration number. Make sure that each of the 5 threads finish the ith iteration of the loop before they can start the (i+1)th iteration (i.e. all threads synchronize/rendezvous towards the end of each iteration). I need to use a two-phase barrier implemented using POSIX semaphores to enforce the synchronization constraint
I wrote following code am I correct ?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int thread_count;
void* MyThread(void* rank);
int main()
{
long thread;
pthread_t* thread_handles;
thread_count = 5;
thread_handles = malloc (thread_count*sizeof(pthread_t));
for (thread = 0; thread < thread_count; thread++)
pthread_create(&thread_handles[thread],NULL,MyThread,(void*) thread);
for (thread = 0; thread < thread_count; thread++)
pthread_join(thread_handles[thread], NULL);
free(thread_handles);
return 0;
}
void* Hello(void* rank)
{
long my_rank = (long) rank;
int a,i;
a=0;
for(i=0;i<10;i++)
{
int n = 5;
int count = 0;
pthread_mutex_t mutex = Semaphore(1)
barrier = Semaphore(0)
a = a + 0.9*MAX_INT;
printf("this is %d iteration\n",i);
mutex.wait()
count = count + 1
mutex.signal()
if count == n: barrier.signal() # unblock ONE thread
barrier.wait()
barrier.signal()
}
}
Edit:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
typedef struct {
int n;
int count;
sem_t mutex;
sem_t turnstyle;
sem_t turnstyle2;
} barrier_t;
void init_barrier(barrier_t *barrier, int n)
{
barrier->n = n;
barrier->count = 0;
sem_init(&barrier->mutex, 0, 1);
sem_init(&barrier->turnstyle, 0, 0);
sem_init(&barrier->turnstyle2, 0, 0);
}
void phase1_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (++barrier->count == barrier->n) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstyle);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstyle);
}
void phase2_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (--barrier->count == 0) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstyle2);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstyle2);
}
void wait_barrier(barrier_t *barrier)
{
phase1_barrier(barrier);
phase2_barrier(barrier);
}
#define NUM_THREADS 5
void *myThread(void *);
int main(int argc, char **argv)
{
pthread_t threads[NUM_THREADS];
barrier_t barrier;
int i;
init_barrier(&barrier, NUM_THREADS);
for (i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, myThread, &barrier);
}
for (i = 0; i < NUM_THREADS, i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
void *myThread(void *arg)
{
barrier_t *barrier = arg;
int i,a;
for(i=0;i<10;i++)
{
a = a + 0.9*MAX_INT;
printf("this is %d iteration\n",i);
}
return NULL;
}
OK, if we examine the Barrier object in, "The Little Book of Semaphores", section 3.7.7, we see that we need a mutex and 2 semaphores called turnstile and turnstile2 (a mutex can be a semaphore that is initialized to 1).
Since we have to use POSIX semaphores, pthreads, and INT_MAX, we start by including the requisite header files:
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>
The book makes the Barrier an object; however, in C, we don't really have objects, but we can create a struct with some functions to operate on it:
typedef struct {
int n;
int count;
sem_t mutex;
sem_t turnstile;
sem_t turnstile2;
} barrier_t;
We can create a function to initialize a barrier:
void init_barrier(barrier_t *barrier, int n)
{
barrier->n = n;
barrier->count = 0;
sem_init(&barrier->mutex, 0, 1);
sem_init(&barrier->turnstile, 0, 0);
sem_init(&barrier->turnstile2, 0, 0);
}
And implement the phase1 function, as in the book:
void phase1_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (++barrier->count == barrier->n) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstile);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstile);
}
Note that the sem_post function only posts a single time, so a loop is required to post the turnstile n times.
The phase2 function also follows directly in the same manner:
void phase2_barrier(barrier_t *barrier)
{
sem_wait(&barrier->mutex);
if (--barrier->count == 0) {
int i;
for (i = 0; i < barrier->n; i++) {
sem_post(&barrier->turnstile2);
}
}
sem_post(&barrier->mutex);
sem_wait(&barrier->turnstile2);
}
Finally, we can implement the wait function:
void wait_barrier(barrier_t *barrier)
{
phase1_barrier(barrier);
phase2_barrier(barrier);
}
Now, in your main function, you can allocate and initialize a barrier and pass it to your spawned threads:
#define NUM_THREADS 5
void *myThread(void *);
int main(int argc, char **argv)
{
pthread_t threads[NUM_THREADS];
barrier_t barrier;
int i;
init_barrier(&barrier, NUM_THREADS);
for (i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, myThread, &barrier);
}
for (i = 0; i < NUM_THREADS, i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
And finally, implement the thread:
void *myThread(void *arg)
{
barrier_t *barrier = arg;
int i;
int a;
for (i = 0; i < 10; i++) {
for (a = 0; a < 0.9*INT_MAX; a++);
printf("this is %d iteration\n", i);
wait_barrier(barrier);
}
return NULL;
}

How to make a code for critical section in c for n processes(Bakery algorithm)

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 :)

producer and consumer with mutexes and pthreading

So I am having a little trouble with the producer and consumer problem with 2 threads and mutexes. What I am trying to do is have the producer fill an array with 10 1's. Then the consumer consumes each 1 and makes it a 0. This filling and emptying just repeats 10 times. Here is what I have so far but it gets stuck on the first cycle:
#include <stdio.h>
#include <pthread.h>
#define N 10
pthread_mutex_t mut;
pthread_cond_t condc,condp;
int queue[N];
int buffer;
void* prod() {
int i;
for(i = 0; i<10; i++) {
pthread_mutex_lock(&mut);
while(queue[N] != 0) {
pthread_cond_wait(&condp, &mut);
}
int k = 0;
for(k=0; k<10; k++) {
queue[k] = 1;
}
pthread_cond_signal(&condc);
pthread_mutex_unlock(&mut);
printf("\nproduced\n");
}
pthread_exit(0);
}
void* cons() {
int i;
for(i = 0; i<10; i++) {
pthread_mutex_lock(&mut);
while(queue[N] == 0) {
pthread_cond_wait(&condc, &mut);
}
int k = 0;
for(k=0; k<10; k++) {
queue[k] = 0;
}
pthread_cond_signal(&condp);
pthread_mutex_unlock(&mut);
printf("\nconsumed\n");
}
pthread_exit(0);
}
main() {
pthread_t producer, consumer;
pthread_mutex_init(&mut, 0);
pthread_cond_init(&condc, 0);
pthread_cond_init(&condp, 0);
pthread_create(&consumer,NULL,&cons, NULL);
pthread_create(&producer,NULL,&prod, NULL);
pthread_join(producer,0);
pthread_join(consumer,0);
pthread_cond_destroy(&condc);
pthread_cond_destroy(&condp);
pthread_mutex_destroy(&mut);
return 0;
}
You don't initialize the members of queue to any particular value before you start reading them. Also, you read queue out of range -- it has ten values but you read the eleventh. Lastly, you are never changing the value you read -- you set the first ten values, which you never look at.

"Segmentation fault" in multithreading with priority by c in linux

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.

My consumer thread isn't reading my producer thread's products correctly

so I'm doing a school project involving creating two pthreads, one that acts as a producer, one that acts as a consumer, communicating via a shared bounded buffer. I threw in some debugging lines that print a statement on the console each time the producer creates a new int to put in the buffer, and displays another line when the consumer is reading the number. It looks like they stay in synch for the first two, with the producer making one item, the consumer reading one item, etc., and then the producer makes everything, and the consumer just reads the final product, ignoring the ones in the middle. Here's my code:
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
pthread_cond_t empty;
pthread_cond_t full;
int done = 0;
pthread_mutex_t lock;
int in = 0;
int out = 0;
int BUFFER_SIZE = 5;
int buffer[5];
void *consumer();
void *producer();
int main() {
pthread_t tidC;
pthread_t tidP;
pthread_cond_init(&empty, NULL);
pthread_cond_init(&full, NULL);
pthread_create(&tidP, NULL, &producer, NULL);
pthread_create(&tidC, NULL, &consumer, NULL);
pthread_join(tidC, NULL);
pthread_join(tidP, NULL);
return 0;
}
void * producer() {
int seed = 6;
int reps = 7;
int num = 0;
int i = 0;
srand(seed);
printf("Producer in for\n");/*DEBUG*/
for(i; i<reps; i++) {
printf("Producer making item %d\n", i);
num = rand();
while(pthread_cond_signal(&full))
{
pthread_cond_wait(&empty, &lock);
}
pthread_mutex_lock(&lock);/*entering critical section*/
buffer[in] = num;
pthread_cond_signal(&full);
pthread_mutex_unlock(&lock);/*exiting critical section*/
in++;
if(in == BUFFER_SIZE) {
in = 0;
}
}
done = 1;
}
void * consumer() {
int num = 0;
int min=0;
int max=0;
int avg=0;
int numItems=0;
int first=1;
int reps = 3;
int sum = 0;
printf("Consumer Entering While\n");/*DEBUG*/
while(!done) {
while(pthread_cond_signal(&empty)){
pthread_cond_wait(&full, &lock);
}
printf("Consumer reading item %d\n", numItems);
pthread_mutex_lock(&lock); /*enter critical section*/
num = buffer[out];
pthread_cond_signal(&empty);
pthread_mutex_unlock(&lock); /*exit critical section*/
out++;
if(out == BUFFER_SIZE)
out = 0;
/*processing*/
if(first) {
min = num;
max = num;
sum = num;
first = 0;
numItems = 1;
}
else {
if(num < min)
min = num;
sum =+ num;
if(num>max)
max = num;
numItems++;
}
}
avg = sum/numItems;/*calc avg*/
/*report stats*/
printf("Minimum: %d\n", min);
printf("Maximum: %d\n", max);
printf("Average: %d\n", avg);
printf("Items Produced: %d\n", numItems);
}
My output is then:
Producer in for
Consumer Entering While
Producer making item 0
Consumer reading item 0
Producer making item 1
Producer making item 2
Producer making item 3
Producer making item 4
Producer making item 5
Producer making item 6
Consumer reading item 1
Minimum: 2726
Maximum: 25069
Average: 12534
Items Produced: 2
Any advice???
Now my output's showing the producer making a few, the consumer
reading a few (asynchronously), and it only reading 5 items (it's
supposed to read 6).
That's due to your use of the variable done - the producer sets done = 1 shortly after it has made item 6, and the consumer tests !done before it reads an item, so it may well exit the while loop without having read and processed the last items. See below for a possible solution.
when I add a return void to the functions, I get an error, "expected
primary expression before 'void'.
Of course - we cannot return a type; e. g. return NULL would be correct.
Here's a version of producer() and consumer() that incorporates several improvements (note that I renamed the condition variables empty and full to nonfull and nonempty, respectively, to accurately describe their meaning):
void *producer()
{
int seed = 6;
int reps = 7;
int num;
int i = 0;
srand(seed);
printf("Producer in for\n");/*DEBUG*/
for (; i<reps; i++)
{
num = rand();
pthread_mutex_lock(&lock);/*entering critical section*/
if (in == out+BUFFER_SIZE) // buffer full?
pthread_cond_wait(&nonfull, &lock); // if so, wait
printf("Producer making item %d\n", i);
buffer[in++%BUFFER_SIZE] = num;
pthread_cond_signal(&nonempty);
pthread_mutex_unlock(&lock);/*exiting critical section*/
}
done = i;
return NULL;
}
void *consumer()
{
int num;
int min;
int max;
int avg;
int numItems = 0;
int first = 1;
int sum = 0;
printf("Consumer Entering While\n");/*DEBUG*/
while (!done || numItems < done)
{ // loop as long as not all produced items are consumed
pthread_mutex_lock(&lock); /*enter critical section*/
if (out == in) // buffer empty?
pthread_cond_wait(&nonempty, &lock); // if so, wait
printf("Consumer reading item %d\n", numItems);
num = buffer[out++%BUFFER_SIZE];
pthread_cond_signal(&nonfull);
pthread_mutex_unlock(&lock); /*exit critical section*/
/*processing*/
if (first)
{
min = num;
max = num;
first = 0;
}
if (num < min) min = num;
sum =+ num;
if (num > max) max = num;
numItems++;
}
avg = sum/numItems;/*calc avg*/
/*report stats*/
printf("Minimum: %d\n", min);
printf("Maximum: %d\n", max);
printf("Average: %d\n", avg);
printf("Items Produced: %d\n", numItems);
return NULL;
}

Resources