How can I generate threads deadlock on MacOs? - c

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...

Related

Execution of pthreads in particular order?

I am been trying to write a program (for learning) in which there will be two threads (A and B) and both threads should execute one after the another. For example, if threads just display/prints Thread A and Thread B, then they should print in that particular order forever.
The desired output is
In Thread: thread1
In Thread: thread2
In Thread: thread1
In Thread: thread2
....
The program that I have wrote uses conditional variables for synchronisation. I have tired mutex and semaphore but they do guarantee mutual exclusivity but they don't print the information in a particular order. I understand that issue is related to scheduling of the threads by scheduler and it is possible that the thread which has just released the mutex, can lock it again immediately. See this link for link for more information.
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
int thread1_ret = 0;
void *thread1(void *arg)
{
while (1) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("In Thread: %s\r\n", __func__);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
thread1_ret = 5;
return &thread1_ret;
}
int thread2_ret = 0;
void *thread2(void *arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
while (1) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("In Thread: %s\r\n", __func__);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
thread2_ret = 5;
return &thread2_ret;
}
int main(int argc, char *argv[])
{
pthread_t t1, t2;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
pthread_create(&t1, &attr, thread1, NULL);
pthread_create(&t2, &attr, thread2, NULL);
pthread_attr_destroy(&attr);
void *ret;
pthread_join(t1, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
pthread_join(t2, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
return 0;
}
My program is working properly but it stops printing after some time (2-3 seconds). I couldn't locate the bug in my code. It would be great if someone direct me with some other solution to achieve the same thing in more efficient and standard method (if there are other standard and efficient methods to solve such problem statement).
Condition variable notifications get lost when no thread is waiting in pthread_cond_wait and spurious wakes-ups happen, so the code must rather wait for a change of a shared state.
Working example:
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
unsigned state = 0;
int thread1_ret = 0;
void *thread1(void *arg)
{
unsigned state_copy;
pthread_mutex_lock(&mutex);
state_copy = state;
pthread_mutex_unlock(&mutex);
while(1) {
pthread_mutex_lock(&mutex);
while(state_copy == state)
pthread_cond_wait(&cond, &mutex);
state_copy = ++state;
printf("In Thread: %s\r\n", __func__);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
thread1_ret = 5;
return &thread1_ret;
}
int thread2_ret = 0;
void *thread2(void *arg)
{
unsigned state_copy;
pthread_mutex_lock(&mutex);
state_copy = ++state;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
while (1) {
pthread_mutex_lock(&mutex);
while(state_copy == state)
pthread_cond_wait(&cond, &mutex);
state_copy = ++state;
printf("In Thread: %s\r\n", __func__);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
thread2_ret = 5;
return &thread2_ret;
}
int main(int argc, char *argv[])
{
pthread_t t1, t2;
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
void *ret;
pthread_join(t1, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
pthread_join(t2, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
return 0;
}
Note that the above code signals the condition variable after releasing the mutex. That is a micro-optimization, however, if FIFO order in waking up waiting threads is required then the mutex must be locked while signalling. See pthread_cond_signal:
The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal().

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 use mutex in C for multithread?

I have 4 processed called A, B, C, D in 4 thread, They printf their name. I want use mutex to process A, B, C, D run in order A, B, C, D. This is my code but it don't work such as me think. How to they work?
#include <stdio.h>
#include <pthread.h>
void processA();
void processB();
void processC();
void processD();
pthread_mutex_t mutex;
void main(){
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
pthread_t thread4;
pthread_mutex_init(&mutex,NULL);
pthread_create(&thread1, NULL, (void *)&processA,NULL);
pthread_create(&thread2, NULL, (void *)&processB,NULL);
pthread_create(&thread3, NULL, (void *)&processC,NULL);
pthread_create(&thread4, NULL, (void *)&processD,NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
pthread_join(thread4, NULL);
pthread_mutex_destroy(&mutex);
}
void processA()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("A \n");
pthread_mutex_unlock(&mutex);
}
}
void processB()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("B \n");
pthread_mutex_unlock(&mutex);
}
}
void processC()
{
while (1)
{
pthread_mutex_lock(&mutex);
printf("C \n");
pthread_mutex_unlock(&mutex);
}
}
void processD()
{
pthread_mutex_lock(&mutex);
while (1)
{
pthread_mutex_lock(&mutex);
printf("D \n");
pthread_mutex_unlock(&mutex);
}
}
mutex is for creating mutual exclusion on some context. For example if you have an object that should be reached by one thread at a time, you can use mutex.
You should use 3 semaphores for implementing such feature. You can say:
//semaphore1 = up, semaphore2 = up, semaphore3 = up
//Thread A
//wait for semaphore1 is up
//work
//make semaphore1 down
//Thread B
//wait for semaphore1 is down
//work
//make semaphore2 down
//Thread C
//wait for semaphore2 is down
//work
//make semaphore3 down
//Thread D
//wait for semaphore3 is down
//work
Well this is how you can do it, you just use mutex for the mutual variable (f in this case) and a pthread conditional signal to trigger the action of one thread per second. All of the threads get the signal but only one can access the mutex.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <stdarg.h>
#include <pthread.h>
pthread_mutex_t v1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t v2 = PTHREAD_COND_INITIALIZER;
int f = 0;
void *processA(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("A,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
return NULL;
}
void *processB(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("B,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
return NULL;
}
void *processC(){
while(1){
pthread_mutex_lock(&v1);
pthread_cond_wait(&v2,&v1);
printf("C,%d\n",f);
f++;
pthread_mutex_unlock(&v1);
}
void main(){
pthread_t *h;
int i,ptnum = 3;
h = malloc(sizeof(pthread_t)*ptnum);
pthread_create(&h[0],NULL,processA,NULL);
pthread_create(&h[1],NULL,processB,NULL);
pthread_create(&h[2],NULL,processC,NULL);
while(f<=30){
pthread_cond_signal(&v2);
sleep(1);
}
pthread_mutex_lock(&v1);
printf("Main Mutex\n");
for(i=0;i<ptnum;i++){
pthread_join(&h[i],PTHREAD_CANCELED);
}
pthread_mutex_unlock(&v1);
return NULL;
}

pthread_join function kill the thread after execution or we need to call pthread_cancel/pthread_exit?

pthread_join() function kill the thread after execution or we need to call pthread_cancel()/pthread_exit()?
I am calling pthread_cancel()/pthread_kill() which is returning 3 ie no thread attached with thread_id.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
void * run (void *);
int main() {
pthread_t p1, p2;
int a = 9;
printf("%d\n", pthread_create(&p1, NULL, &run, (void*)&p1));
printf("%d\n", pthread_create(&p2, NULL, &run, (void*)&p2));
printf("%d\n", pthread_join(p1, NULL));
//usleep(1000);
printf("%d\n", pthread_join(p2, NULL));
printf("before exit\n");
printf("%d\n", pthread_cancel(p1));
printf("after exit\n");
printf("%d\n", pthread_cancel(p2));
printf("both thread exited\n");
printf("%d\n", pthread_join(p1, NULL));
printf("%d\n", pthread_join(p2, NULL));
printf("terminated\n");
printf("%d\n", pthread_kill(p1, 0));
printf("%d\n", pthread_kill(p2, 0));
printf("ext\n");
printf("%d\n", pthread_join(p1, NULL));
printf("%d\n", pthread_join(p2, NULL));
printf("jion\n");
return 0;
}
void *run (void *p) {
int *i = (int*)p;
printf("created i = %d\n", *i);
}
This is the code i am using. in this pthread_cancel on wards all function returning 3 which means thread is being already killed.
pthread_join does not kill the thread, it waits for the thread to complete. If you want to kill a thread then use pthread_kill. But that has to be done before pthread_join, otherwise the thread has already exited.
pthread_cancel requests that the thread teminate at the next cancellation point, and is probably safer than using pthread_kill.
pthread_exit exits the current thread.
Some context would be nice... but if you're just waiting for a thread (presumably you only have one you care about) to terminate/return, then pthread_join is good enough.
The pthread_join() function waits for the thread specified by thread
to terminate. If that thread has already terminated, then pthread_join() returns
immediately.
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html
Check the man page for usage/warnings.
After pthread_join() Add
/* Last thing that main() should do */
pthread_exit(NULL);
For more details pls refer here.
pthread_join() is used to make the main() thread wait till all the threads completes it's execution. Control reaches the pthread_join(), when that particular thread completes it's execution.
So if you try to cancel/kill that particular thread, error will be returned.
Sample Code
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 4
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n",tid);
pthread_exit((void*) t); //Exits that current thread.
}
int main (int argc, char *argv[])
{
pthread_t thread[NUM_THREADS];
int rc;
long t;
void *status;
for(t=0; t<NUM_THREADS; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, BusyWork, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Wait for completion */
for(t=0; t<NUM_THREADS; t++) {
rc = pthread_join(thread[t], &status);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
}
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // Exits main thread.
}
For #Joachim Pileborg
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 4
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n",tid);
for(i = 0; i <10000000; i++)
printf("\n Thread: %ld, %d", tid, i);
pthread_exit((void*) t); //Exits that current thread.
}
int main (int argc, char *argv[])
{
pthread_t thread[NUM_THREADS];
int rc;
long t;
void *status;
for(t=0; t<NUM_THREADS; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, BusyWork, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
//printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // Exits main thread(work will be done).
//return 0;//( Threads will exit once main exits.)
}

pthread_join blocks my code

can you explain me why the following use of pthread_join doesn't work?it blocks my code.
if I comment those 3 lines, my code does what is expected, but obviously I don't know if threads are terminated(in my code there is no problem for that, but in a bigger situation there is).
int k=0;
pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER;
struct primi{
int s;
int temp;
};
struct example{
int c;
struct primi primissimi;
};
void *funzione_thread(void* args);
void prepare(void){
printf("preparing locks...\n");
pthread_mutex_lock(&mutex); }
void parent(void){
printf("parent unlocking locks...\n");
pthread_mutex_unlock(&mutex);}
void child(void){
printf("child unlocking locks...\n");
pthread_mutex_unlock(&mutex); }
void *thr_fn(void *arg){
printf("thread started...\n");
return(0);}
void *funzione_thread(void* args){
pthread_mutex_lock(&mutex);
struct example *exthread = args;
struct example locale = *exthread;
locale.primissimi.s++;pthread_mutex_unlock(&mutex);
printf("local is %d original is %d\n",locale.primissimi.s,exthread->primissimi.s);
exthread->primissimi.s = locale.primissimi.s;
printf("after it is%d\n",exthread->primissimi.s);
pthread_exit(NULL);
}
int ffork(struct example *extmp){
pthread_t id[5];
int i;
while(k<3){
k++;
pthread_create(&id[k],NULL,funzione_thread,extmp);
}
printf("now k is %d\n\n",k);
for(i=1;i<=3;i++){
pthread_join( id[i] ,NULL );
printf("waited thread %d\n",i);
}
printf("threads completed\n");
pthread_exit (NULL);
//return 1;
}
int main(int argc, char** argv){
struct example *ex = malloc(sizeof(*ex));
int pid,tmp;
pthread_t tid;
if ((err = pthread_atfork(prepare, parent, child)) != 0){
printf("can't install fork handlers");
exit(-1);}
pthread_create(&tid, NULL, thr_fn, 0);
sleep(1);
pid=fork();
if(pid==0){
ex->c=1;
ex->primissimi.s=1;
if((tmp=ffork(ex))!=1){
printf("errore in ffork\n");
sleep(2);
exit(0);
}
else{printf("tutto ok in ffork\n");
sleep(2);
exit(0);
}
}//fine figlio
else{
sleep(10);
}
return 0;
}
Your code has no protection against calling fork with the mutex locked. Since the thread that locked the mutex doesn't exist in the child, it cannot unlock the mutex ... ever. Any thread in the child that tries to acquire the mutex will deadlock, waiting for the non-existent thread to release the lock.
There are a lot of possible fixes, but the simplest is probably to hold the mutex across the call to fork. You can use an atfork handler to do this. Arrange the handler to acquire the mutex before the fork and release it after (in both the parent and child).
You really need to know what you're doing to use fork together with pthreads, unless you're going to immediately exec in the child.

Resources