pthread_cancel() does not cancel a thread as it should - c

I am testing a signal handler for my OS Class project.
Basically my signal handler (which is running in it's own thread) have to handle SIGINT, this means that it has to "kill" all the other threads and then exit.
unfortunately my code does not work.
This is my dummy thread task, which I want to stop with a SIGINT
static void * dummyTask(){
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
while(1){
pthread_testcancel();
printf(" Hello!\n");
sleep(2);
}
return NULL;
}
Here is my main. As you can see I create the signal handler and then up to 2 dummy threads.
I save their thID in an array, I need this later in the task of the signal handler thread, as you will see
int main(){
//need to the signal handler thread, so it can kill all the threads with cancel
pthread_t **thids = malloc( 2 * sizeof(pthread_t *));
sigset_t set;
pthread_t signalHandlerThread;
sigemptyset(&set);
sigaddset(&set, SIGINT);
//s is for error checking, not importanto now
int s = pthread_sigmask(SIG_BLOCK, &set, NULL);
//shParam: signalHandlerParam
signalHParam *shParam = malloc(sizeof(signalHParam));
shParam->set = &set;
shParam->arrayOfThIDs = thids;
s = pthread_create(&signalHandlerThread, NULL, signalHandlerTask, (void *) shParam);
for(int i = 0; i < 2; i ++){
pthread_t dummyThread;
pthread_create(&dummyThread, NULL, &dummyTask, NULL);
thids[i] = &dummyThread;
}
pause();
//pthread_join(signalHandlerThread, NULL);
return 1;
}
As you can see the signalHandlerThread execute a function named signalHandlerTask, which is:
static void *signalHandlerTask(void *shParam){
signalHParam *tmp = (signalHParam *) shParam;
sigset_t *set = tmp->set;
int s, sig;
int i = sigismember(set, SIGINT);
if(i != 1)
printf("error\n");
while(1 == 1){
s = sigwait(set, &sig);
if(sig == SIGINT){
printf("\n----- signal recived ----\n");
//function that use the array to kill threads
killThreads(tmp->arrayOfThIDs);
pthread_exit(NULL); //kill the signal handler thread
}
}
}
The shParam is a struct that I use to pass multiple arguments to the task of the thread (signalHandlerTask) and it is like this
typedef struct{
pthread_t **arrayOfThIDs;
sigset_t *set;
} signalHParam;
Finally we are at the real issue. I created the killThreads function as follows:
void killThreads(pthread_t **thids){
for(int i = 0; i < 2; i++){
int r = pthread_cancel(*thids[i]);
if(r != 0)
printf("error!! %d\n", r);
//r is 3, why??
pthread_join(*thids[i], NULL);
}
}
The problem is, as said, that pthread_cancel(*thids[i]) not work, threads are left alive and I can't figure out why
Here is the entire code for those who wants to run it:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <error.h>
#include <unistd.h>
#include <errno.h>
typedef struct{
pthread_t **arrayOfThIDs;
sigset_t *set;
} signalHParam;
void killThreads(pthread_t **thids){
//termino il threadListener, e tutti i thread nel thread pool
for(int i = 0; i < 2; i++){
//FAI ANCHE SU PROGETTO!!
int r = pthread_cancel(*thids[i]);
if(r != 0)
printf("pthread_cancel failed: %s\n", strerror(r));
//FAI ANCHE SU PROGETTO!!
pthread_join(*thids[i], NULL);
}
}
static void *signalHandlerTask(void *shParam){
signalHParam *tmp = (signalHParam *) shParam;
sigset_t *set = tmp->set;
int s, sig;
int i = sigismember(set, SIGINT);
if(i != 1)
printf("error\n");
while(1 == 1){
s = sigwait(set, &sig);
if(sig == SIGINT){
printf("\n----- signal recived ----\n");
//function that use the array to kill threads
killThreads(tmp->arrayOfThIDs);
pthread_exit(NULL); //kill the signal handler thread
}
}
}
static void * dummyTask(){
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
//printf("mo aspetto 10s\n");
//sleep(10);
while(1){
pthread_testcancel();
printf(" Ciao!\n");
sleep(2);
}
return NULL;
}
int main(){
//need to the signal handler thread, so it can kill all the threads with cancel
pthread_t **thids = malloc( 2 * sizeof(pthread_t *));
sigset_t set;
pthread_t signalHandlerThread;
sigemptyset(&set);
sigaddset(&set, SIGINT);
//s is for error checking, not importanto now
int s = pthread_sigmask(SIG_BLOCK, &set, NULL);
//shParam: signalHandlerParam
signalHParam *shParam = malloc(sizeof(signalHParam));
shParam->set = &set;
shParam->arrayOfThIDs = thids;
s = pthread_create(&signalHandlerThread, NULL, signalHandlerTask, (void *) shParam);
for(int i = 0; i < 2; i ++){
pthread_t dummyThread;
pthread_create(&dummyThread, NULL, &dummyTask, NULL);
thids[i] = &dummyThread;
}
pthread_join(signalHandlerThread, NULL);
return 1;
}

Having run the full program myself, it turns out that the only important bug is the one I originally pointed out in the comments. (There are a bunch of style problems and places where I wouldn't have done it that way, but none of them rises to the level of "bug". There is one minor unrelated bug: you forgot to include stdio.h and signal.h.)
for(int i = 0; i < 2; i ++){
pthread_t dummyThread;
pthread_create(&dummyThread, NULL, &dummyTask, NULL);
thids[i] = &dummyThread;
}
This creates a single variable named dummyThread (whether or not it is declared inside the loop) and writes all of the thread handles into that variable. All of the thids[i] pointers are set to point to that one variable. Since a single pthread_t variable can only hold a single thread handle, you lose the thread handles created on all but the last iteration of the loop. Later, the signal handler thread will attempt to cancel the same thread repeatedly, will succeed the first time, and fail the remaining N-1 times. (To make it more obvious what's going on, increase the number of threads and notice that the program prints "pthread_cancel failed: No such process" exactly N-1 times, no matter what N is.)
The correction is simply to use an array of pthread_t instead of an array of pthread_t *, and write the thread handles directly into the array:
typedef struct{
pthread_t *arrayOfThIDs;
sigset_t *set;
} signalHParam;
void killThreads(pthread_t **thids){
//termino il threadListener, e tutti i thread nel thread pool
for(int i = 0; i < 2; i++){
//FAI ANCHE SU PROGETTO!!
int r = pthread_cancel(thids[i]);
if(r != 0)
printf("pthread_cancel failed: %s\n", strerror(r));
//FAI ANCHE SU PROGETTO!!
pthread_join(*thids[i], NULL);
}
}
// ...
int main(){
//need to the signal handler thread, so it can kill all the threads with cancel
pthread_t *thids = malloc( 2 * sizeof(pthread_t));
sigset_t set;
pthread_t signalHandlerThread;
sigemptyset(&set);
sigaddset(&set, SIGINT);
//s is for error checking, not importanto now
int s = pthread_sigmask(SIG_BLOCK, &set, NULL);
//shParam: signalHandlerParam
signalHParam *shParam = malloc(sizeof(signalHParam));
shParam->set = &set;
shParam->arrayOfThIDs = thids;
s = pthread_create(&signalHandlerThread, NULL, signalHandlerTask,
(void *) shParam);
for(int i = 0; i < 2; i ++){
pthread_create(&thids[i], NULL, &dummyTask, NULL);
}
pthread_join(signalHandlerThread, NULL);
return 1;
}
signalHandlerTask and dummyTask are basically correct as-is.

Related

Can I signal multiple threads simultaneously with pthread_cond_wait(,)?

I am writing various code snippets and see what happens. The code below was intended to delay all threads until all reached a certain point in the code and then make each print a distinctive number. Since the threads all do that, the numbers should occur in a random order.
My current problem is that I keep they threads busy waiting. If the number of threads gets big, the program slows down significantly.
I would like to change that by using signals, I found pthread_cond_wait() for that, however I don't see how one would use that to signal all threads that they would please wake up.
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define threads 10
int counter=0;
pthread_mutex_t lock;
void handler(void *v) {
pthread_mutex_lock(&lock);
counter++;
printf("%d\n", counter);
pthread_mutex_unlock(&lock);
while(counter != threads); // busy waiting
printf("I am first! %d\n", v);
}
int main() {
pthread_t t[threads];
for(int i =0; i < threads; i++) {
pthread_create(&t[i], NULL, handler, (void*) i);
}
for(int i =0; i < threads; i++) {
pthread_join(t[i], NULL);
}
return 0;
}
EDIT: I changed the code to the following, however, it still does not work :/
pthread_mutex_t lock;
pthread_cond_t cv;
void handler(void *v) {
pthread_mutex_lock(&lock);
pthread_cond_wait(&cv, &lock);
printf("I am first! %d\n", v);
pthread_mutex_unlock(&lock);
}
int main() {
pthread_t t[threads];
for(int i =0; i < threads; i++)
pthread_create(&t[i], NULL, handler, (void*) i);
sleep(2);
pthread_cond_signal(&cv);
for(int i =0; i < threads; i++)
pthread_join(t[i], NULL);
return 0;
}
use broadcast()?
http://pubs.opengroup.org/onlinepubs/009696699/functions/pthread_cond_broadcast.html
The pthread_cond_broadcast() function shall unblock all threads currently blocked on the specified condition variable cond.
The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).
An alternative solution to pthread_cond_broadcast() might be the following.
You define a read-write mutex and lock it in write in the main thread before creating the other threads. The other threads will try to acquire a read-lock but since the main thread have a write-lock they will be blocked.
After the creation of all thread the main-thread releases the lock. All the other threads will be waken up and since many read-locks can coexist the will execute simultaneously (i.e. no one will be locked).
Code might be something like:
pthread_rwlock_t lock;
void handler(void *v) {
if ((res = pthread_rwlock_rdlock(&lock)!=0)
{
exit(1);
}
printf("I am first! %d\n", v);
pthread_rwlock_unlock(&lock);
}
int main() {
pthread_t t[threads];
//First acquire the write lock:
if ((res = pthread_rwlock_wrlock(&lock)!=0)
{
exit(1);
}
for(int i =0; i < threads; i++)
{
pthread_create(&t[i], NULL, handler, (void*) i);
//it is not clear if you want sleep inside the loop or not
// You indented it as if to be inside but not put brackets
sleep(2);
}
pthread_rwlock_unlock(&lock);
for(int i =0; i < threads; i++)
pthread_join(t[i], NULL);
pthread_rwlock_destroy(&lock);
return 0;
}
Try posting the matching remove_from_buffer code.
Better yet, Short, Self Contained, Correct Example
Make a short main() with two threads.
One thread adds to the buffer at random intervals.
The other thread removes from the buffer at random intervals.
Example
CELEBP22
/* CELEBP22 */
#define _OPEN_THREADS
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
int footprint = 0;
void *thread(void *arg) {
time_t T;
if (pthread_mutex_lock(&mutex) != 0) {
perror("pthread_mutex_lock() error");
exit(6);
}
time(&T);
printf("starting wait at %s", ctime(&T));
footprint++;
if (pthread_cond_wait(&cond, &mutex) != 0) {
perror("pthread_cond_timedwait() error");
exit(7);
}
time(&T);
printf("wait over at %s", ctime(&T));
}
main() {
pthread_t thid;
time_t T;
struct timespec t;
if (pthread_mutex_init(&mutex, NULL) != 0) {
perror("pthread_mutex_init() error");
exit(1);
}
if (pthread_cond_init(&cond, NULL) != 0) {
perror("pthread_cond_init() error");
exit(2);
}
if (pthread_create(&thid, NULL, thread, NULL) != 0) {
perror("pthread_create() error");
exit(3);
}
while (footprint == 0)
sleep(1);
puts("IPT is about ready to release the thread");
sleep(2);
if (pthread_cond_signal(&cond) != 0) {
perror("pthread_cond_signal() error");
exit(4);
}
if (pthread_join(thid, NULL) != 0) {
perror("pthread_join() error");
exit(5);
}
}
OUTPUT
starting wait at Fri Jun 16 10:54:06 2006 IPT is about ready to
release the thread wait over at Fri Jun 16 10:54:09 2006

(C, pthreads) Let multiple threads synchronize and continue together

I have a program which consists of multiple threads.
These threads have to synchronize at some point, continue together, do their work of different lengths and then synchronize again.
Here's the example of what I mean:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define NUM_THREADS 10
void* thread(void* idp);
int threads_running = 0;
pthread_mutex_t* mutex;
pthread_cond_t* cond;
int main(int args, char **argv)
{
pthread_mutex_t mutex_var;
pthread_cond_t cond_var;
mutex = &mutex_var;
cond = &cond_var;
pthread_mutex_init(mutex, NULL);
pthread_cond_init(cond, NULL);
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++)
{
printf("Creating Thread %d....\n", i);
int* id = malloc(sizeof(int));
*id = i;
if(0 != pthread_create(&threads[i], NULL, thread, (void *) id))
{
perror("Error while creating the threads");
exit(1);
}
}
for (int i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
void* thread(void* idp)
{
int* id = (int*) idp;
while (1)
{
sleep(*id+2); // Thread work
pthread_mutex_lock(mutex);
threads_running++;
pthread_mutex_unlock(mutex);
pthread_cond_broadcast(cond);
printf("Thread %d WAIT\n", *id);
fflush(stdout);
// Let threads synchronize
pthread_mutex_lock(mutex);
while(threads_running != NUM_THREADS)
{
pthread_cond_wait(cond, mutex);
}
pthread_mutex_unlock(mutex);
printf("Thread %d WAKEUP\n", *id);
fflush(stdout);
// and continue
pthread_mutex_lock(mutex);
threads_running--;
pthread_mutex_unlock(mutex);
}
}
The thing that happens, is that some (usually #9 and one or two others) reach Thread %d WAKEUP but before the others can wake-up threads_running is already smaller than NUM_THREADS.
How can I synchronize multiple threads, so they continue together?
I am having some trouble wrapping my head around the parallel accesses to variables.
I found the answer seconds later:
Change while(threads_running != NUM_THREADS) to while(threads_running != 0 && threads_running != NUM_THREADS)
Change threads_running--; to threads_running = 0;
Now it works perfectly.
I recommend using pthread_cond_signal() than pthread_cond_broadcast(cond);
So the code flow where while loop is exiting looks like below.
pthread_mutex_lock(mutex);
while(threads_running != 0 && threads_running != NUM_THREADS)
{
pthread_cond_wait(cond, mutex);
}
pthread_cond_signal(cond);
So the final code looks like this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#define NUM_THREADS 10
void* thread(void* idp);
int threads_running = 0;
pthread_mutex_t* mutex;
pthread_cond_t* cond;
int main(int args, char **argv)
{
pthread_mutex_t mutex_var;
pthread_cond_t cond_var;
mutex = &mutex_var;
cond = &cond_var;
pthread_mutex_init(mutex, NULL);
pthread_cond_init(cond, NULL);
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++)
{
printf("Creating Thread %d....\n", i);
int* id = malloc(sizeof(int));
*id = i;
if(0 != pthread_create(&threads[i], NULL, thread, (void *) id))
{
perror("Error while creating the threads");
exit(1);
}
}
for (int i = 0; i < NUM_THREADS; i++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
void* thread(void* idp)
{
int* id = (int*) idp;
while (1)
{
sleep(*id+2); // Thread work
pthread_mutex_lock(mutex);
threads_running++;
pthread_mutex_unlock(mutex);
printf("Thread %d WAIT\n", *id);
fflush(stdout);
// Let threads synchronize
pthread_mutex_lock(mutex);
while(threads_running != 0 && threads_running != NUM_THREADS)
{
pthread_cond_wait(cond, mutex);
}
pthread_cond_signal(cond);
pthread_mutex_unlock(mutex);
printf("Thread %d WAKEUP\n", *id);
fflush(stdout);
// and continue
pthread_mutex_lock(mutex);
threads_running = 0;
pthread_mutex_unlock(mutex);
}
}

C Threads - Sync

I have this code, I am trying to create n threads, Do some work in each thread, and then reap each thread. If n thread is even, use detach, and if odd, use join,
When i run the program, it first prints out Successfully reaped thread, then doing working, then successfully reaped thread... looks like i have some synchronization issues
Do I even need to use Mutex?
Can anyone help me with getting everything running in the right order?
Thank you
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
void *dowork(){
//Do whatever needs to be done in each thread here
pthread_mutex_lock(&lock);
long tid = (long) pthread_self();
printf("Doing Work ...for %ld\n",tid);
pthread_mutex_unlock(&lock);
//pthread_exit(NULL);
return;
}
void spawn(int n){
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
exit (1);
}
int i=0;
//pthread_t * thread = malloc(sizeof(pthread_t)*n);
pthread_t threads[n];
while (i<n) {
if(pthread_create(&(threads[i]), NULL, dowork, NULL) != 0){
printf ("Create pthread error!\n");
exit (1);
}
i++;
}//End of while
// Wait for threads to complete //
i = 0;
while (i<n)
{
int success = -1;
if(i%2 == 0){
success=pthread_detach(threads[i]);
}
else{
success=pthread_join(threads[i], NULL);
}
if(success==0)
printf("Succesfully reaped thread\n");
i++;
}
pthread_mutex_destroy(&lock);
}
int main() {
spawn(5);
}

make several threads with mutex and different lifetimes

void process(int number, int time) {
printf("Prosess %d kjører\n", number);
sleep(time);
printf(" Prosess %d terminated after %d sekunder\n", number, time);
}
int main(void) {
pid_t pid[7];
int status= 0;
if((pid[1]= fork())== 0) {
process(1, 1);
exit(0);
}
if((pid[3]= fork())== 0) {
process(3, 3);
exit(0);
}
waitpid(pid[1], NULL, 0);
if((pid[5]= fork())== 0) {
process(5, 3);
exit(0);
}
if((pid[2]= fork())== 0) {
process(2, 2);
exit(0);
}
waitpid(pid[3], NULL, 0);
//waitpid(pid[2], NULL, 0);
if((pid[4]= fork())== 0) {
process(4, 2);
exit(0);
}
waitpid(pid[5], NULL, 0);
if((pid[6]= fork())== 0) {
process(6, 3);
exit(0);
}
wait(NULL);
while(wait(&status)> 0) {
//We just wait for the children to finish their processes
}
printf("All processes is now terminated\n");
return 0;
}
How can I turn this code to do the same, but instead use pthread and mutex?? We're asked to make a struct method with id (There shall be 6 threads, wich each sleep a different times.), sec (sleeptime) and int signal[6].
Its a school task, and we dont get any c-training. Please help.
You would synchronize access to any shared data between the different threads by the same mutex and you would then do a join_all in the main thread to wait for all threads to finish.
I leave implementation up to the reader.
sem_t sem[6]; /* one semaphore for each thread */
struct threadargs {
int id; /* thread number */
int sec; /* how many seconds to sleep */
int signal[6]; /* which threads to signal when done */
};
void* tfunc(void *arg) {
int i;
struct threadargs *targs=arg;
// VENT PÅ DIN EGEN SEMAFOR
sem_wait(&sem[targs->id-1]);
printf("Tråd %d kjører\n", targs->id);
sleep(targs->sec);
printf("Tråd %d er ferdig og vekker kanskje andre...\n", targs->id);
// ITERATE OVER Signal-array and wake up thread nr "i" if Signal[i] is 1
for(i= 0; i< 6; i++) {
if(targs->signal[i]== 1)
sem_post(&sem[i]);
}
}
int main(void)
{
int i,j;
pthread_t tid[6];
struct threadargs *targs[6];
/* allocate memory for threadargs and zero out semaphore signals */
for(i=0;i<6;i++) {
targs[i] = (struct threadargs*) malloc(sizeof(struct threadargs));
for(j=0;j<6;j++)
targs[i]->signal[j]=0;
}
targs[0]->id=1; /* thread number 1 */
targs[0]->sec=1; /* how long to sleep */
targs[0]->signal[1]=1; /* which threads to wake up when done */
targs[0]->signal[4]=1;
// INITIALIZES THREADS SEMAPHORE TO 1 OR 0
sem_init(&sem[0], SHARED, 1);
// START THREAD
pthread_create(&tid[0], NULL, tfunc, (void*) targs[0]);
targs[1]->id= 2; /* thread number 2 */
targs[1]->sec=2; /* how long to sleep */
targs[1]->signal[3]=1; /* which threads to wake up when done */
sem_init(&sem[1], SHARED, 0);
pthread_create(&tid[1], NULL, tfunc, (void*) targs[1]);
targs[2]->id= 3; /* thread number 3 */
targs[2]->sec=3; /* how long to sleep */
sem_init(&sem[2], SHARED, 0);
pthread_create(&tid[2], NULL, tfunc, (void*) targs[2]);
targs[3]->id= 4; /* thread number 4 */
targs[3]->sec=2; /* how long to sleep */
sem_init(&sem[3], SHARED, 0);
pthread_create(&tid[3], NULL, tfunc, (void*) targs[3]);
targs[4]->id= 5; /* thread number 5 */
targs[4]->sec=3; /* how long to sleep */
targs[4]->signal[5]=1; /* which threads to wake up when done */
sem_init(&sem[4], SHARED, 0);
pthread_create(&tid[4], NULL, tfunc, (void*) targs[4]);
targs[5]->id= 6; /* thread number 6 */
targs[5]->sec=3; /* how long to sleep */
sem_init(&sem[5], SHARED, 0);
pthread_create(&tid[5], NULL, tfunc, (void*) targs[5]);
for(i=0;i<6;i++)
pthread_join(tid[i], NULL);
return 0;
}
This is the code I used. Pthreads with semaphores =)
Thank you for your help!

pthread_join doesn't work

What I want to accomplish:
In the main function are created two threads. They increment a global variable with the number 5. And send a signal to consumer thread that decrements the variables.In the consumer thread between each decrementation the current value is displayed. The main thread has to wait until all the threads are finished and then exit.
What I get:
Some times the main function exits before the consumer had a chance to display the results. I'm using pthread_join, but it returns error code 3.
Any Ideas how to get the wanted results?
The code is bellow.
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
static pthread_mutex_t mtx;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *producer(void *arg);
void *consumer(void *arg);
static int avail = 0;
int main(int argc, char *argv[]){
pthread_t cons1, prod1, prod2;
int status;
int t1;
int t2;
int t3;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_mutexattr_t mtxAttr;
pthread_mutexattr_settype(&mtxAttr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mtx, &mtxAttr);
t1 = pthread_create(&prod1, &attr, producer, NULL);
if(t1 != 0){
perror("problem1");
}
t2 = pthread_create(&prod2, &attr, producer, NULL);
if(t2 != 0){
perror("problem2");
}
t3 = pthread_create(&cons1, &attr, consumer, NULL);
if(t3 != 0){
perror("problem3");
}
status = pthread_join(t1, NULL);
if(status != 0){
perror("can't join1");
}
status = pthread_join(t2, NULL);
if(status != 0){
perror("can't join2");
printf("\n%d\n", status);
}
status = pthread_join(t3, NULL);
if(status != 0){
printf("%s",strerror(errno));
}
printf("\nend result \t%d\n",avail);
printf("fin\n");
//while(1){}
return 0;
}
void *producer(void *arg){
int s;
printf("producer\n");
s = pthread_mutex_lock(&mtx);
avail+=5;
s = pthread_mutex_unlock(&mtx);
s = pthread_cond_signal(&cond);
pthread_exit(NULL);
}
void *consumer(void *arg){
int s;
while(1) {
s = pthread_mutex_lock(&mtx);
if(s !=0 ){
perror("lock err");
}
while (avail == 0) {
s = pthread_cond_wait(&cond, &mtx);
}
while (avail > 0) {
avail--;
printf("Temp: %d \n",avail);
}
s = pthread_mutex_unlock(&mtx);
}
printf("done");
pthread_exit(NULL);
}
Don't join on t1, t2 or t3. Those are the return codes of the pthread_create() function. Use pthread_join() on prod1, prod2 and cons1 instead. And please compile with -Wall -Wextra.

Resources