How to make two threads execute alternately? - c

I have two functions f1() and f2() I want f1() and f2() to execute
alternately, without using a loop: Not like this : loop {
f1();
f2(); }
I just want to use thread method My code is below:
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<semaphore.h>
void *f1(void *vargp);
void *f2(void *vargp);
static sem_t mutex;
int main(int argc, char **argv) {
pthread_t tid1, tid2;
sem_init(&mutex, 0, 1);
pthread_create(&tid1, NULL, f1, NULL);
pthread_create(&tid2, NULL, f2, NULL);
sleep(100);
return 0;
}
void *f1(void *vargp) {
pthread_detach(pthread_self());
while (1) {
sem_wait(&mutex);
printf("In f1\n");
sleep(1);
sem_post(&mutex);
}
return NULL;
}
void *f2(void *vargp) {
pthread_detach(pthread_self());
while(1) {
sem_wait(&mutex);
printf("In f2\n");
sleep(1);
sem_post(&mutex);
}
return NULL;
}
The result always prints "In f1" What should I do ?

Related

How i must use rand_r()?

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

How can I generate threads deadlock on MacOs?

I'm learning to handle threads deadlock, but by executing the C code on my terminal, execution does not generate deadlocks even if it should. Can anyone tell me why and possibly how to force the deadlock?
#include<pthread.h>
#include<semaphore.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
void *func(void *p);
pthread_mutex_t m1,m2;
int main(){
pthread_t tid[2];
pthread_attr_t attr;
pthread_attr_init(&attr);
int id[2];
for(int i=0;i<2;i++){
id[i]=i;
pthread_create(&tid[i],&attr,func,(&id[i]));
}
pause();
}
void *func(void *p){
int *i=p;
while(1){
if(*i==0){
pthread_mutex_lock(&m1);
pthread_mutex_lock(&m2);
printf("I'm Thread %d\n", *i);
pthread_mutex_unlock(&m1);
pthread_mutex_unlock(&m2);
}
else{
pthread_mutex_lock(&m2);
pthread_mutex_lock(&m1);
printf("I'm Thread %d\n", *i);
pthread_mutex_unlock(&m1);
pthread_mutex_unlock(&m2);
}
}
pthread_exit(0);
}
Change the assignment of the variable in your thread:
int *i=(int *)p;
You need to point to the argument else both threads run the same lock unlock sequence. Where you call pthread_create there is a implicit cast.
I could not figure out how to get your code to deadlock. I was able to get the following example to deadlock on macOS:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
typedef struct {
const char *mutex_name;
pthread_mutex_t *pmutex;
} mutex_data_t;
typedef struct {
const char *thread_name;
mutex_data_t mutex_list[2];
} thread_data_t;
void *deadlock(void *data) {
thread_data_t *pthread_data = data;
const char *name = pthread_data->thread_name;
printf("%s: Starting...\n", name);
printf("%s: Locking %s...\n", name, pthread_data->mutex_list[0].mutex_name);
pthread_mutex_lock(pthread_data->mutex_list[0].pmutex);
printf("%s: Sleeping...\n", name);
sleep(1);
printf("%s: Locking %s...\n", name, pthread_data->mutex_list[1].mutex_name);
pthread_mutex_lock(pthread_data->mutex_list[1].pmutex);
printf("Done\n");
return NULL;
}
int main()
{
pthread_mutex_t mutex1;
pthread_mutex_t mutex2;
mutex_data_t mutex1_data = { "mutex1", &mutex1 };
mutex_data_t mutex2_data = { "mutex2", &mutex2 };
thread_data_t thread1_data = { "thread1", { mutex1_data, mutex2_data }};
thread_data_t thread2_data = { "thread2", { mutex2_data, mutex1_data }};
pthread_t thread1;
pthread_t thread2;
pthread_mutex_init(&mutex1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_create(&thread1, NULL, deadlock, &thread1_data);
pthread_create(&thread2, NULL, deadlock, &thread2_data);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
Output
thread1: Starting...
thread2: Starting...
thread1: Locking mutex1...
thread2: Locking mutex2...
thread1: Sleeping...
thread2: Sleeping...
thread1: Locking mutex2...
thread2: Locking mutex1...

Conditional Variables with Posix Threads

I want to print for infinity the below message "What a wonderful world!" , I have from the begin the 3 threads to do this job the first one "What a , second one "Wonderful" and third one "world" , ( I am giving as parameter in ./a.out 3) , the problem in the below code is that the message displayed like this : What a wonderful what a wonderful the World is missing. I think Something is bad with the conditional variables, any suggestions?
int p;
void *disp(void *arg);
pthread_mutex_t muta,mutb,mutc;
pthread_cond_t condition_cond= PTHREAD_COND_INITIALIZER;
void *disp(void *arg)
{
int id=*(int*)arg;
free(arg);
arg=0;
pthread_mutex_lock(&muta);
while (id==0)
{
pthread_cond_wait (&condition_cond,&muta);
}
printf("What a");
pthread_mutex_unlock(&muta);
pthread_mutex_lock(&mutb);
while (id==1)
{
pthread_cond_wait (&condition_cond,&mutb);
}
printf(" Wonderful");
pthread_mutex_unlock(&mutb);
pthread_mutex_lock(&mutc);
while(id==2)
{
pthread_cond_wait (&condition_cond,&mutc);
}
printf(" World!\n");
pthread_mutex_unlock(&mutc);
return NULL;
}
EDIT: updated code based on the answer by dbush:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
int p;
void *disp(void *arg);
pthread_mutex_t mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3= PTHREAD_COND_INITIALIZER;
void *disp(void *arg)
{
int id=*(int*)arg;
free(arg);
arg=0;
pthread_mutex_lock(&mut);
while(1)
{
if (id==0)
{
pthread_cond_wait (&cond1,&mut);
printf("What a ");
pthread_cond_signal (&cond2);
}
else if(id==1)
{
pthread_cond_wait (&cond2,&mut);
printf(" wonderful ");
pthread_cond_signal (&cond3);
}
else if(id==2)
{
pthread_cond_wait (&cond3,&mut);
printf(" world!\n ");
pthread_cond_signal (&cond1);
}
}
return NULL;
}
int main (int argc,char *argv[])
{
int i;
pthread_t *tid;
if(argc!=2)
{
printf("Provide number of threads.\n");
exit(1);
}
p=atoi(argv[1]);
tid=(pthread_t *) malloc (p*sizeof(pthread_t));
if (tid==NULL)
{
printf("Could not allocate memory.\n");
exit(1);
}
for (i=0;i<p;++i)
{
int *a;
a=malloc(sizeof(int)); //pointer to pass
*a=i;
pthread_create(&tid[i],NULL,disp,a);
}
pthread_cond_signal(&cond1);
for (i=0;i<p;++i)
pthread_join(tid[i],NULL);
return 0;
}
You've got your usage of mutexes and condition variables reversed. You need one mutex to control all three threads, and three condition variables (one for each thread).
After each thread finishes its work, it should signal the next thread using the condition variable for the target thread. Additionally, the main function needs to signal the first thread to get things started. You'll want it to sleep for a brief period so that all threads have time to start.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *disp(void *arg);
pthread_mutex_t mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2= PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3= PTHREAD_COND_INITIALIZER;
void *disp(void *arg)
{
int id=*(int*)arg;
free(arg);
arg=0;
pthread_mutex_lock(&mux);
while (1) {
if (id==0) {
pthread_cond_wait (&cond1,&mux);
printf("What a");
pthread_cond_signal(&cond2);
} else if (id == 1) {
pthread_cond_wait (&cond2,&mux);
printf(" Wonderful");
pthread_cond_signal(&cond3);
} else if (id == 2) {
pthread_cond_wait (&cond3,&mux);
printf(" World!\n");
pthread_cond_signal(&cond1);
}
}
return NULL;
}
int main()
{
pthread_t t1, t2, t3;
int *id = malloc(sizeof(int));
*id=0;
pthread_create(&t1, NULL, disp, id);
id = malloc(sizeof(int));
*id=1;
pthread_create(&t2, NULL, disp, id);
id = malloc(sizeof(int));
*id=2;
pthread_create(&t3, NULL, disp, id);
sleep(1);
pthread_cond_signal(&cond1);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
return 0;
}

how to call threads from other c program

I have a program which is creating two threads but all of this is done in a single c program here is the code
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
void * thread1()
{
int i=0;
while(1)
{
printf("%d Hello!!\n", i);
i++;
}
}
void * thread2()
{
int j;
while(1)
{
printf("%d How are you?\n", j);
j++;
}
}
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
now if
void * thread1()
{
int i=0;
while(1)
{
printf("%d Hello!!\n", i);
i++;
}
}
is defined in another program for example mythread1.c
and
void * thread2()
{
int j;
while(1)
{
printf("%d How are you?\n", j);
j++;
}
}
is defined in another c program for example mythread2.c
then how can i call these in my test.c program
test.c
int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, thread1, NULL);
pthread_create(&tid2, NULL, thread2, NULL);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
return 0;
}
Please guide me is there any way to do this using Linux system call!

Not able to get mutex locks to prevent threads from accessing a function

Working on the Producer and Consumer problem for a class and having trouble just putting on the final touches. The problem I am encountering is that i think my mutex locks are not locking my threads out of the function. For example if I run the program and pass it the parameters 2 4 4 7 it would print 8 7's and then 2 seconds later it will print 8 8's and then 8 9's and so on. I have tried using trylock and moving around the semaphores but to no avail. Is there something that I am missing when that is causing none of the threads to be locked out?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
typedef int buffer_item;
#define BUFFER_SIZE 5
#define TRUE 1
buffer_item START_NUMBER;
int counter;
int insert_item(buffer_item item);
int remove_item(buffer_item *item);
buffer_item buffer[BUFFER_SIZE];
void* producer(void *ptr);
void* consumer(void *ptr);
pthread_cond_t condc, condp;
pthread_mutex_t mutex;
int sleepTime, producerThreads, consumerThreads,a;
pthread_attr_t attr;
sem_t full, empty;
int insert_item(buffer_item item)
{
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else {
return -1;
}
}
int remove_item(buffer_item *item)
{
if(counter > 0) {
*item = buffer[(counter-1)];
counter--;
return 0;
}
else {
return -1;
}
}
void* producer(void *ptr) {
buffer_item item;
item = START_NUMBER;
while(TRUE) {
sleep(sleepTime);
sem_wait(&empty);
pthread_mutex_lock(&mutex);
if(insert_item(item)) {
fprintf(stderr, "error \n");
}
else {
printf("producer%u produced %d\n", (unsigned int)pthread_self(),item);
item++;
}
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
}
void* consumer(void *ptr) {
buffer_item item;
while(TRUE) {
sleep(sleepTime);
sem_wait(&full);
pthread_mutex_lock(&mutex);
if(remove_item(&item)) {
fprintf(stderr, "error \n");
}
else {
printf("consumer%u consumed %d\n", (unsigned int)pthread_self(),item);
}
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
}
void initializeData() {
pthread_mutex_init(&mutex, NULL);
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFFER_SIZE);
pthread_attr_init(&attr);
counter = 0;
}
int main(int argc, char **argv) {
sleepTime = atoi(argv[1]);
producerThreads = atoi(argv[2]);
consumerThreads = atoi(argv[3]);
START_NUMBER = atoi(argv[4]);
initializeData();
pthread_t pro, con;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condc, NULL);
pthread_cond_init(&condp, NULL);
for(a=0; a< consumerThreads;a++)
pthread_create(&con, NULL, consumer, NULL);
for(a=0;a<producerThreads;a++)
pthread_create(&pro, NULL, producer, NULL);
pthread_join(con, NULL);
pthread_join(pro, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condc);
pthread_cond_destroy(&condp);
sleep(sleepTime);
}
Thanks for the help Dmitri, after moving around the lines you told me about and some discussion with one of my friends I finally got it to start outputting the right numbers!
This is the output i have been looking for
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
typedef int buffer_item;
#define BUFFER_SIZE 5
#define TRUE 1
buffer_item START_NUMBER;
buffer_item item;
int counter;
int insert_item(buffer_item item);
int remove_item(buffer_item *item);
buffer_item buffer[BUFFER_SIZE];
void* producer(void *ptr);
void* consumer(void *ptr);
pthread_cond_t condc, condp;
pthread_mutex_t mutex;
int sleepTime, producerThreads, consumerThreads, a, item;
pthread_attr_t attr;
sem_t full, empty;
int insert_item(buffer_item item)
{
if(counter < BUFFER_SIZE) {
buffer[counter] = item;
counter++;
return 0;
}
else {
return -1;
}
}
int remove_item(buffer_item *item)
{
if(counter > 0) {
*item = buffer[(counter-1)];
printf("consumer%u consumed %d\n", (unsigned int)pthread_self(),buffer[counter-1]);
counter--;
return 0;
}
else {
return -1;
}
}
void* producer(void *ptr) {
while(TRUE) {
sleep(sleepTime);
sem_wait(&empty);
pthread_mutex_lock(&mutex);
if(insert_item(START_NUMBER)) {
fprintf(stderr, "error \n");
}
else {
printf("producer%u produced %d\n", (unsigned int)pthread_self(),START_NUMBER);
START_NUMBER++;
}
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
}
void* consumer(void *ptr) {
while(TRUE) {
sleep(sleepTime);
sem_wait(&full);
pthread_mutex_lock(&mutex);
if(remove_item(&item)) {
fprintf(stderr, "error \n");
}
else {
// printf("consumer%u consumed %d\n", (unsigned int)pthread_self(),&START_NUMBER);
}
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
}
void initializeData() {
pthread_mutex_init(&mutex, NULL);
sem_init(&full, 0, 0);
sem_init(&empty, 0, BUFFER_SIZE);
pthread_attr_init(&attr);
counter = 0;
}
int main(int argc, char **argv) {
sleepTime = atoi(argv[1]);
producerThreads = atoi(argv[2]);
consumerThreads = atoi(argv[3]);
START_NUMBER = atoi(argv[4]);
item = START_NUMBER;
initializeData();
pthread_t pro, con;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condc, NULL);
pthread_cond_init(&condp, NULL);
for(a=0; a< consumerThreads;a++)
pthread_create(&con, NULL, consumer, NULL);
for(a=0;a<producerThreads;a++)
pthread_create(&pro, NULL, producer, NULL);
pthread_join(con, NULL);
pthread_join(pro, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condc);
pthread_cond_destroy(&condp);
sleep(sleepTime);
}

Resources