How to use this for killing array of threads? - c

This code worked fine , but how to use it to kill for array of remaining threads?
#include<stdio.h>
#include<signal.h>
#include<pthread.h>
void *print1(void *tid)
{
pthread_t *td= tid;
pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock1);
printf("1");
printf("2");
printf("3");
printf("4\n");
printf("Coming out of thread1 \n");
sleep(2);
pthread_mutex_unlock(&lock1);
pthread_kill(*td,SIGKILL);//killing remaining all threads
return NULL;
}
void *print2(void *arg)
{
pthread_mutex_t *lock = arg;
pthread_mutex_lock(lock);
sleep(5);
printf("5");
sleep(5);
printf("6");
sleep(5);
printf("7");
sleep(5);
printf("8\n");
fflush(stdout);
pthread_mutex_unlock(lock);
return NULL;
}
int main()
{
int s;
pthread_t tid1, tid2;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
printf("creating Thread 1and 2 \n");
sleep(2);
pthread_create(&tid1, NULL, print1,&tid2);
pthread_create(&tid2, NULL, print2,&lock);
printf("Running Thread 1\n");
sleep(2);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
Comments: Please delete this and add some extra information about the code. The editor is not allowing me to edit the code.

here is an edited version of the code
along with some commentary
#include<signal.h>
#include<pthread.h>
void *print1(void *tid)
{
// should be in global space, so no need to pass
pthread_t *td= tid;
// this is a whole new mutex,
//should be in global space so other threads can access it
pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;
// why bother with the mutex, it does nothing useful
pthread_mutex_lock(&lock1);
printf("1");
printf("2");
printf("3");
printf("4\n");
printf("Coming out of thread1 \n");
sleep(2);
pthread_mutex_unlock(&lock1);
pthread_kill(*td,SIGKILL);//killing remaining all threads return NULL;
// this exit is not correct, it should be this call:
// void pthread_exit(void *rval_ptr);
} // end function: print1
void *print2(void *arg)
{
// this should be in global memory so all threads using same mutex
pthread_mutex_t *lock = arg;
pthread_mutex_lock(lock);
sleep(5);
printf("5");
sleep(5);
printf("6");
sleep(5);
printf("7");
sleep(5);
printf("8\n");
fflush(stdout);
pthread_mutex_unlock(lock);
// this exit is not correct, it should be this call:
// void pthread_exit(void *rval_ptr);
return NULL;
} // end function: print2
int main()
{
int s;
// this should be in global memory
// so no need to pass to threads
pthread_t tid1, tid2;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
printf("creating Thread 1and 2 \n");
// why bother to sleep here?
sleep(2);
// in these calls, the last parm should be NULL
// and the related data should be in global memory
pthread_create(&tid1, NULL, print1,&tid2);
pthread_create(&tid2, NULL, print2,&lock);
// we are still in main, so this printf is misleading
printf("Running Thread 1\n");
// no need to sleep()
// as the pthread_join calls will wait for the related thread to exit
sleep(2);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
} // end function: main

However you want. There is no "one right way" to do this.
Probably the easiest way is to replace your calls to sleep with calls to a function that uses pthread_cond_timedwait and a predicate that causes the thread to call pthread_exit.
In psuedo-code, replace calls to sleep with this logic:
Compute the time to sleep until.
Lock the mutex.
Check if the predicate is set to exit, if so, call pthread_exit.
Call pthread_cond_timedwait.
Check if the predicate is set to exit, if so, call pthread_exit.
Check if the time expired, if not, go to stop 4.
And to terminate the threads, do this:
Lock the mutex.
Set the predicate to exit.
Call pthread_cond_broadcast.
Release the mutex.
Call pthread_join on the threads to wait until they've terminated.

Related

Thread synchronisation using semaphore for c

I am writing a c program to create three threads(1,2,3) such that at any given point of time only one thread must execute and print the output on console in the order 123123123123.........
I am making use of semaphore for synchronization.
I am having an issue with the code i have written. the code doesn't print it in the order 123123... the order is random and stops after a while.
#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<unistd.h>
#include<assert.h>
#include<stdlib.h>
sem_t sem_1;
void *func1(void *arg){
int err1=0;
while(1){
err1=sem_wait(&sem_1);
assert(err1==0);
printf("thread 1\n");
}
//return NULL;
}
void *func2(void *arg){
int err2=0;
while(1){
err2=sem_wait(&sem_1);
assert(err2==0);
printf("thread 2\n");
}
// return NULL;
}
void *func3(void *arg){
int err3=0;
while(1){
err3=sem_wait(&sem_1);
assert(err3==0);
printf("thread 3\n");
}
// return NULL;
}
int main(){
pthread_t *t1,*t2,*t3;
int i=0,rc=0,c1=0,c2=0,c3=0;
t1=(pthread_t *)malloc(sizeof(*t1));
t2=(pthread_t *)malloc(sizeof(*t2));
t3=(pthread_t *)malloc(sizeof(*t3));
i=sem_init(&sem_1,0,1);
assert(i==0);
c1=pthread_create(t1,NULL,func1,NULL);
assert(c1==0);
c2=pthread_create(t2,NULL,func2,NULL);
assert(c2==0);
c3=pthread_create(t3,NULL,func3,NULL);
assert(c3==0);
while(1){
rc=sem_post(&sem_1);
assert(rc==0);
sleep(1);
}
return 0;
}
Why would you even expect them in in an order?
Your threads do things inbetween the different waits, and according to the system scheduler, these can take different amount of time.
printf is a buffered operation that gives you exclusive access to a shared resource. So in addition to your semaphore there is a hidden lock somewhere, that also regulates the progress of your threads. Don't expect the prints to appear in order, even if the calls themselves are.
Then, for the end, using assert here is really a very bad idea. All sem_t operations can (and will) fail spuriously, so it is really bad to abort, just because such a failure.
In fact, sem_t is really a low level tool, and you should never use it without checking return values and without having a fall back strategy if such a call fails.
Of course. I can't see any order related synchronization mechanism.
One of the options to achieve the strict order is to have one semaphore per thread:
sem_t sem[3];
// ...
while(1) {
for(n = 0; n < 3; n++) {
rc=sem_post(&sem[n]);
assert(rc==0);
}
sleep(1);
}
Below Code will help to solve the problem, one semaphore for each thread used to achieve synchronization. The initial value of the semaphore does the job. used usleep to launch thread in sequence manner for needed output. The same can be done by using Mutex lock and cond variables
//declaring semaphore
sem_t sema1;
sem_t sema2;
sem_t sema3;
void* t1(void *arg)
{
for(int j=0;j<10;j++)
{
sem_wait(&sema1);
printf("Thread 1 \n");
sem_post(&sema2);
}
printf("T1 return\n");
return NULL;
}
void* t2(void *arg)
{
for(int j=0;j<10;j++)
{
sem_wait(&sema2);
printf("Thread 2 \n");
sem_post(&sema3);
}
printf("T2 return\n");
return NULL;
}
void* t3(void *arg)
{
for(int j=0;j<10;j++)
{
sem_wait(&sema3);
printf("Thread 3 \n");
sem_post(&sema1);
}
printf("T3 return \n");
return NULL;
}
int main()
{
pthread_t tid1, tid2,tid3;
sem_init(&sema1,0,1);
sem_init(&sema2,0,0);
sem_init(&sema3,0,0);
pthread_create(&tid1, NULL, t1, NULL);
usleep(100);
pthread_create(&tid2, NULL, t2, NULL);
usleep(100);
pthread_create(&tid3, NULL, t3, NULL);
pthread_join(tid3, NULL);
pthread_join(tid2, NULL);
pthread_join(tid1, NULL);
sem_destroy(&sema1);
sem_destroy(&sema2);
sem_destroy(&sema3);
return 0;
}

Simple example for pthread_join deadlock

I am looking for a very simple example to demonstrate a deadlock using pthread_join; however, this is not trivial.
I started with this:
void* joinit(void* tid)
{
pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
pthread_join(thread2, NULL);
return 0;
}
But however, it says 'EINVAL' (invalid argument) because thread2 is not yet specified when pthread_create for thread1 is called.
Any ideas?
If you're just wanting to demonstrate that a pthread_join can cause a deadlock, you could do something similar to the following code:
#include <stdio.h>
#include <pthread.h>
void* joinit(void* tid)
{
printf("In %#x, waiting on %#x\n", pthread_self(), (*((pthread_t*)tid)));
pthread_join((*((pthread_t*)tid)), NULL);
printf("Leaving %#x\n", pthread_self());
return NULL;
}
int main(void)
{
pthread_t thread1 = pthread_self();
pthread_t thread2;
pthread_create(&thread2, NULL, joinit, &thread1);
joinit(&thread2);
return 0;
}
This will cause the main thread to wait on the spawned thread and the spawned thread to wait on the main thread (causing a guaranteed deadlock) without the need for extra locking primitives to clutter up what you are trying to demonstrate.
And to answer some of your questions more directly:
it says 'EINVAL' (invalid argument) because thread2 is not yet specified when pthread_create for thread1 is called.
... and from one of your comments ...
I tried this and it worked, but the problem is, it only works SOMETIMES because sometimes I get EINVAL again.
In your code, you call pthread_create consecutively to spawn the 2 threads:
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
In your joinit code, you grab the thread handle passed in to join on:
pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
The reason this sometimes works and others you'll get EINVAL has to do with time slices allocated to each thread's context and sequencing. When the first pthread_create is called you will have a valid handle to thread1 after it returns but the handle to thread2 is not valid yet, at least not until the 2nd pthread_create is called.
To this, when a thread is created, the act of the thread coming "alive" (i.e. the thread function actually running) could take some extra time even though the thread handle returned is valid. In these instances, there is a chance one thread can execute more code than might be "expected". In your code, both pthread_create functions might happen to have been called in the time slice allocated for the main thread which could give each spawned thread enough "time" before hitting the pthread_join statement allowing tid_c to point to a valid handle; in the EINVAL case, pthread_create(&thread1, NULL, joinit, &thread2) was called and the spawned thread hit the pthread_join(*tid_c, NULL) before pthread_create(&thread2, NULL, joinit, &thread1) could give thread2 a valid handle (causing the error).
If you wanted to keep your code similar to how it is now, you would need to add a lock of some sort to ensure the threads don't exit or call anything prematurely:
#include <stdio.h>
#include <pthread.h>
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* joinit(void* tid)
{
/* this can be above the lock because it will be valid after lock is acquired */
pthread_t* tid_c = (pthread_t*)tid;
int retval = -1;
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
printf("%#x waiting on %#x\n", pthread_self(), *tid_c);
retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
/* get the lock in the main thread FIRST */
pthread_mutex_lock(&lock);
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
/* by this point, both handles are "joinable", so unlock */
pthread_mutex_unlock(&lock);
/* can wait on either thread, but must wait on one so main thread doesn't exit */
pthread_join(thread2, NULL);
return 0;
}
Hope this can help.
The main reason for your error is that you have two threads each waiting for the same thread to terminate because of the call to pthread_join in main. Another problem is that you don't ensure each thread correctly sees the other thread's ID.
Fix it like this:
#include <stdio.h>
#include <pthread.h>
pthread_t thread1;
pthread_t thread2;
pthread_mutex_t mutex;
pthread_cond_t cond;
int go = 0;
void* joinit(void* ptr)
{
// wait until both thread IDs are known
pthread_mutex_lock(&mutex);
while (go == 0)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
pthread_t* tid_c = *((pthread_t**) ptr);
printf("About to wait\n");
int retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
// tell the other threads we're done
pthread_mutex_lock(&mutex);
go++;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
// setup synchronization
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
// tell the threads to go
pthread_mutex_lock(&mutex);
go = 1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
// wait for both threads to finish
pthread_mutex_lock(&mutex);
while (go != 3)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
return 0;
}

I killed single thread by using following code. How to kill array of threads using this code?

#include<stdio.h>
#include<signal.h>
#include<pthread.h>
void *print1(void *tid) {
pthread_t *td= tid;//assigning argument to pointer td
pthread_mutex_t lock1=PTHREAD_MUTEX_INITIALIZER;//mutex for synchronization
printf("Running Thread 1\n");
pthread_mutex_lock(&lock1);
printf("1");
printf("2");
printf("3");
printf("4\n");
printf("Coming out of thread1\n");
sleep(2);
pthread_mutex_unlock(&lock1);
pthread_kill(*td,SIGKILL);//or we can use pthread_cancel(*td) killing thread 2
pthread_exit(NULL);
} void *print2(void *arg) {
pthread_mutex_t *lock = arg;//acquiring lock
pthread_mutex_lock(lock);
sleep(5); //sleeps for 5 sec
printf("5");
sleep(5);//sleeps for 5 sec
printf("6");
sleep(5);//sleeps for 5 sec
printf("7");
sleep(5);//sleeps for 5 sec
printf("8\n");
pthread_mutex_unlock(lock);
pthread_exit(NULL);
} int main() {
int s;
pthread_t tid1, tid2;//thread id's
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
printf("creating Thread 1and 2 \n");
sleep(2);
pthread_create(&tid1, NULL, print1,&tid2);//creating thread1
pthread_create(&tid2, NULL, print2,&lock);//creating thread2
sleep(2);
pthread_join(tid1, NULL);//joing to execute thread1
pthread_join(tid2, NULL);
return 0; }
You can kill one or more threads using any method you choose. You are writing the code the threads run, so you can code them to terminate under whatever conditions you like. There's no particular restrictions.
Your code doesn't kill one thread, by the way.
The SIGKILL signal is sent to a process to cause it to terminate immediately (kill). In contrast to SIGTERM and SIGINT, this signal cannot be caught or ignored, and the receiving process cannot perform any clean-up upon receiving this signal. -- Wikipedia
So you told one thread to kill the process, which it did. If you ever feel you need to force a thread to do something, that means you didn't code the thread to do what you wanted it to do in the first place. Instead of trying to kill a thread, code that thread to terminate itself.

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.

How to use mutexes in C

I am confused about use of multiple mutexes in C.
int main() {
pthread_t thread1;
char *message1 = "Thread 1";
int r;
pthread_mutex_init(&mutex1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_mutex_lock(&mutex1);
r = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
printf("Parent 1\n");
pthread_mutex_lock(&mutex2);
printf("Parent 2\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
pthread_join( thread1, NULL);
printf("Thread 1 returns: %d\n",r);
return 0;
}
void *print_message_function( void *str ) {
pthread_mutex_lock(&mutex1);
char *message;
message = (char *) str;
printf("Child 1 received message: %s \n", message);
pthread_mutex_lock(&mutex2);
printf("child 2\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
return NULL;
}
output is
Parent 1
Parent 2
Child 1 received message: Thread 1
child 2
Thread 1 returns: 0
what i want is
Parent 1
Child 1 received message: Thread 1
Parent 2
child 2
Thread 1 returns: 0
When you call pthread_create you have already locked mutex1. That means that every other thread that calls pthread_mutex_lock(&mutex1); will wait for the mutex to be unlocked. That is what happen when you create a second thread: mutex1 is already locked, so the second thread cannot enter the critical section but need to wait for the mutex to be unlocked. That happens at the end of the main function.
You'll need to reorganize your code to get the output you desire.
However, to obtain such a result you should check synchronization systems, such semaphores or condition variables; they will provide a clearer and easier way to synchronize threads.
You may also check this tutorial: POSIX Threads Programming
A simple solution using semaphores (not tested, but it should work):
#include <stdio.h>
#include <semaphore.h>
sem_t sem1, sem2;
void* f(void* str) {
sem_wait(&sem1);
printf("Child 1 received message: %s \n",(char*)str);
sem_post(&sem2);
sem_wait(&sem1);
printf("Child 2\n");
return NULL;
}
int main (int argc, const char * argv[]) {
pthread_t thread;
char* message = "Thread 1";
int r;
sem_init(&sem1,0,0);
sem_init(&sem2,0,0);
r = pthread_create(&thread, NULL, f, (void*)message);
sem_post(&sem1);
sem_wait(&sem2);
printf("Parent 2\n");
sem_post(&sem1);
pthread_join(thread1, NULL);
printf("Thread 1 returns: %d\n",r);
return 0;
}
Mutexes alone aren't suitable for performing the kind of closely-interlocked execution that you want - their normal use is for protecting access to a shared data structure. This is because they're designed for saying "Thing A shouldn't happen at the same time as Thing B", but they don't say anything about whether Thing A or Thing B happens first or second.
You could use mutexes and condition variables, but in this case your problem is most closely matched by a pthreads Barrier object:
#include <stdio.h>
#include <pthread.h>
pthread_barrier_t barrier;
void *print_message_function( void *str )
{
char *message;
message = (char *) str;
pthread_barrier_wait(&barrier); /* Barrier point 1 */
/* (wait until parent prints first message) */
printf("Child 1 received message: %s \n", message);
pthread_barrier_wait(&barrier); /* Barrier point 2 */
/* (allow parent to proceed and print second message) */
pthread_barrier_wait(&barrier); /* Barrier point 3 */
/* (wait for parent to print second message) */
printf("child 2\n");
return NULL;
}
int main()
{
pthread_t thread1;
char *message1 = "Thread 1";
int r;
pthread_barrier_init(&barrier, NULL, 2);
r = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
printf("Parent 1\n");
pthread_barrier_wait(&barrier); /* Barrier point 1 */
/* (allow child to proceed and print first message) */
pthread_barrier_wait(&barrier); /* Barrier point 2 */
/* (wait for child to print first message) */
printf("Parent 2\n");
pthread_barrier_wait(&barrier); /* Barrier point 3 */
/* (allow child to proceed and print second message) */
pthread_join( thread1, NULL);
/* (wait for child to exit) */
printf("Thread 1 returns: %d\n",r);
return 0;
}
Note that it is not usual to try to tightly interlock the execution of threads in this way - really, you've gone to great pains to ensure that the threads don't execute in parallel at all, which is the whole point of threads in the first place. If you find yourself doing this in a real project, it's a sign that you ought to carefully re-think your design.
I think you need to unlock mutex1 sooner. You unlock it after the printf("Parent 2\n"); so thread1 is still locked waiting for pthread_mutex_lock(&mutex1);.
When thread1 starts it's first step is to lock while it waits for mutual exclusion (clue's in the name) lock on mutex1. So it's paused.
Then you :
printf("Parent 1\n");
pthread_mutex_lock(&mutex2); <-- lock 2 is unleased but thread one is waiting on mutex1
printf("Parent 2\n");

Resources