in this example code below, where is the "critical section" exatly?. after "sem_wait()" ?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
void * thread_snd(void *arg);
void * thread_rcv(void *arg);
sem_t bin_sem;
int number=0;
char thread1[]="A Thread";
char thread2[]="B Thread";
char thread3[]="C Thread";
int main(int argc, char **argv)
{
pthread_t t1, t2, t3;
void *thread_result;
int state;
state = sem_init(&bin_sem, 0, 0);
pthread_create(&t1, NULL, thread_snd, &thread1);
pthread_create(&t2, NULL, thread_rcv, &thread2);
pthread_create(&t3, NULL, thread_rcv, &thread3);
pthread_join(t1, &thread_result);
pthread_join(t2, &thread_result);
pthread_join(t3, &thread_result);
printf("number : %d \n", number);
sem_destroy(&bin_sem);
return 0;
}
void * thread_snd(void * arg)
{
int i;
for(i=0; i<4; i++)
{
while(number != 0)
sleep(1);
number++;
printf("%s, number : %d \n", (char*)arg, number);
sem_post(&bin_sem);
}
}
void * thread_rcv(void * arg)
{
int i;
for(i=0; i<2; i++)
{
sem_wait(&bin_sem);
number--;
printf("%s, number : %d \n", (char*)arg, number);
}
}
There actually is no "critical section" in the provided code, there is only "sync point", and yes that is realized with the semaphore. The critical section can also be implemented with semaphore, but then the thread must use both sem_wait() and sem_post() but in most cases mutexes are used for critical sections (if only one thread is ever supposed to enter it).
Related
This is my code using threads:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *t1(void *arg)
{
FILE *file = fopen((char *) arg, "w");
for (long long int i = 0; i <= 100000000; i++) {
fprintf(file, "--LINE-- <%lld>\n", i);
}
fclose(file);
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t thread1, thread2, thread3, thread4;
pthread_create(&thread1, NULL, t1, "FILE_1.txt");
pthread_create(&thread2, NULL, t1, "FILE_2.txt");
pthread_create(&thread3, NULL, t1, "FILE_3.txt");
pthread_create(&thread4, NULL, t1, "FILE_4.txt");
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
pthread_join(thread4, NULL);
return 0;
}
This is code without threads, I just call the function 4 times:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *t1(void *arg)
{
FILE *file = fopen((char *) arg, "w");
for (long long int i = 0; i <= 100000000; i++) {
fprintf(file, "--LINE-- <%lld>\n", i);
}
fclose(file);
return NULL;
}
int main(int argc, char *argv[])
{
t1("FILE_1.txt");
t1("FILE_2.txt");
t1("FILE_3.txt");
t1("FILE_4.txt");
return 0;
}
I get about the same time as with threads. (I used code to get the time however the question was being flagged as if it was asking how to get the time it takes to run a function so I had to remove it). Is this a problem with fprintf? How could I write to multiple files at the same time? Is there a better solution than using threads?
I'm trying to use semaphores to avoid that a global variable is changed by threads and this variable is supposed to increment within the for loop. My main objective is to protect the variable cnt from the threads so it can increment within the for loop. However, I don't know how to do it because this is the first time I work with semaphores.
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
sem_t semaphore;
int cnt = 0; //global shared variable
void *threadProd(void *param); //threads call this function.
int main(int argc, char *argv[])
{
int niters;
pthread_t tid1, tid2; //thread ids
sem_init(&semaphore,0,1);
if (argc != 2){
printf("Usage: %s <niters>\n", argv[0]);
exit(0);
}
niters = atoi(argv[1]);
pthread_create(&tid1, NULL, threadProd, &niters);
pthread_create(&tid2, NULL, threadProd, &niters);
pthread_join(tid1, NULL); //wait for thread to finish
pthread_join(tid2, NULL);
//check answer:
if(cnt != (2 * niters))
printf("Incorrect answer, cnt = %d\n", cnt);
else
printf("Correct answer, cnt = %d\n", cnt);
sem_destroy(&semaphore);
exit(0);
}
//Thread routine
void *threadProd(void *vargp)
{
sem_wait(&semaphore);
int upper = *((int *) vargp);
for (int i = 0; i < upper; i++)
cnt ++;
sem_post(&semaphore);
return NULL;
}
This is my current code for the Producer-Consumer problem. I compiled it and ran it but nothing is printed. The command line takes in 3 arguments: Sleep time, producer threads, consumer threads. I've tried setting the values as 5, 1, 1 respectively, the sleep timer works but I'm unsure about the rest.
Code for buffer.h:
typedef int buffer_item;
#define BUFFER_SIZE 5
Code for buffer.c:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include "buffer.h"
buffer_item buffer[BUFFER_SIZE];
void *producer(void *param);
void *consumer(void *param);
pthread_mutex_t mutex;
sem_t empty;
sem_t full;
int insert_item(buffer_item item)
{
do
{
wait(empty);
wait(mutex);
signal(mutex);
signal(full);
}while(1);
return 0;
}
int remove_item(buffer_item *item)
{
do
{
wait(full);
wait(mutex);
signal(mutex);
signal(empty);
}while(1);
return 0;
}
int main(int argc, char *argv[])
{
int sleepTime;
int producerThreads;
int consumerThreads;
int counter_1;
int counter_2;
if(argc != 4)
{
return -1;
}
sleepTime = atoi(argv[1]);
producerThreads = atoi(argv[2]);
consumerThreads = atoi(argv[3]);
srand((unsigned)time(NULL));
for(counter_1 = 0; counter_1 < producerThreads; counter_1++)
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, producer, NULL);
}
for(counter_2 = 0; counter_2 < consumerThreads; counter_2++)
{
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tid, &attr, consumer, NULL);
}
sleep(sleepTime);
return 0;
}
void *producer(void *param)
{
buffer_item item;
int randomTime;
int counter_1 = 0;
while(1)
{
randomTime = rand() % 1000 + 1;
sleep(randomTime);
item = rand();
if(insert_item(item))
{
fprintf(stderr, "Error.");
}
else
{
printf("Producer ID: %lu, Produced Item: %d\n", pthread_self(), item);
printf("The buffer now contains %d items\n", counter_1);
++counter_1;
}
}
}
void *consumer(void *param)
{
buffer_item item;
int randomTime;
int counter_2 = 0;
while(1)
{
randomTime = rand() % 1000 + 1;
sleep(randomTime);
if(insert_item(item))
{
fprintf(stderr, "Error.");
}
else
{
printf("Consumer ID: %lu, Consumed Item: %d\n", pthread_self(), item);
printf("The buffer now contains %d items\n", counter_2);
++counter_2;
}
}
}
So far I've tried declaring the tid separately, skipping sleep and join the threads, but it still doesn't print.
Your code can't possibly run, indeed it doesn't even compile.
Here's a list of issues that need to be addressed:
wait should be sem_wait
signal should be sem_post for semaphores
int sem_wait(sem_t *sem); and int sem_post(sem_t *sem); take the pointer to a semaphore
sem_wait(mutex) and sem_post(mutex) give something like "incompatible type for argument 1 of sem_wait", I guess you want to acquire and release the lock on the mutex like pthread_mutex_lock(&mutex) and pthread_mutex_unlock(&mutex)
in the consumer if(insert_item(item)): item is used uninitialized
still in the consumer you use insert_item instead of remove_item
Coming to the main question "I compiled it and ran it but nothing is printed", it doesn't print anything because producer and consumer call, respectively, insert_item and remove_item and are trapped inside infinite loops (e.g. while(1))
I am a student and i encountered a following task using multithreading in c, the problem is I am trying to protect shared variable cnt using P and V operataions. I am using semaphore to protect the shared variable, but it is giving me following errors:
correctcntn.c:15:10: error: expected declaration specifiers or ‘...’ before ‘&’ token
sem_init(&mutex, 0, 1);
^
correctcntn.c:15:18: error: expected declaration specifiers or ‘...’ before numeric constant
sem_init(&mutex, 0, 1);
^
correctcntn.c:15:21: error: expected declaration specifiers or ‘...’ before numeric constant
sem_init(&mutex, 0, 1);
Thank you in advance! Any help is appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include<semaphore.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
void *thread(void *vargp);
volatile long cnt = 0;
sem_t mutex;
sem_init(&mutex, 0, 1);
void P(sem_t *s)
{
sem_wait(&s);
}
void V(sem_t *s)
{
sem_post(&s);
}
int main(int argc, char **argv)
{
long niters;
pthread_t tid1, tid2;
niters = atoi(argv[1]);
pthread_create(&tid1, NULL, thread, &niters);
printf("THREAD 1 with tid= %ld CREATED \n", tid1);
pthread_create(&tid2, NULL, thread, &niters);
printf("THREAD 2 with tid= %ld CREATED \n", tid2);
pthread_join(tid1, NULL);
printf("THREAD 1 with tid= %ld TERMINATED \n", tid1);
pthread_join(tid2, NULL);
printf("THREAD 2 with tid= %ld TERMINATED \n", tid2);
if (cnt != (2 * niters))
printf("BOOM! cnt=%ld\n", cnt);
else
printf("OK cnt=%ld\n", cnt);
exit(0);
}
void *thread(void *vargp)
{
long i, niters = *((long *)vargp);
for (i = 0; i < niters; i++)
P(&mutex);
cnt++;
V(&mutex);
return NULL;
}
Statements to be executed like sem_init(&mutex, 0, 1); must be in function bodies in C.
You should move that inside a function body -- for example, at the beginning of the main() function.
int main(int argc, char **argv)
{
long niters;
pthread_t tid1, tid2;
sem_init(&mutex, 0, 1); /* move to here */
niters = atoi(argv[1]);
It gets me error at rand_r
undefined reference to 'rand_r'
It is my first program at c language
I must use rand_r to threads, but i don't know what to do.
Please help me. Thank you
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "p3160062.h"
int cook;
int oven;
int prep;
int bake;
pthread_mutex_t lock;
pthread_t thread_id[100];
unsigned int seed;
int a;
void *myThread(void *vargp)
{
pthread_mutex_lock(&lock);
a=rand_r(&seed)%6;
while(a==0){
a=rand_r(&seed)%6;
}
printf("a=%d\n",a);
sleep(1);
printf("In thread\n");
pthread_mutex_unlock(&lock);
return NULL;
}
int main(void)
{
seed=1;
int i=0;
printf("Before Thread\n");
for(i=0;i<100;i++){
pthread_create(&(thread_id[i]), NULL, myThread, NULL);
pthread_join(thread_id[i], NULL);
seed++;
}
printf("After Thread\n");
pthread_mutex_destroy(&lock);
exit(0);
}