0

I am new to C and trying out conditional critical region. I read up on a couple of sites about Wait() and Signal() but I just can't figure out what my issue is. Hopefully somebody here can point me in the right direction what I am doing wrong here.

I am trying to do make two threads in my sample program here. Thread 1 will assign a value to String stuff and Thread 2 will print the info of the String.

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mutex;
pthread_cond_t cond;
void Lock(pthread_mutex_t m);
void Unlock(pthread_mutex_t m);
void Wait(pthread_cond_t t, pthread_mutex_t m);
void Signal(pthread_cond_t);
void Broadcast(pthread_cond_t t);
void* First(void* args);
void* Second(void* args);

char* stuff;

int main(int argc, char** argv){
    pthread_t r1, r2;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    if(pthread_create(&r1, NULL, First, NULL))
        fprintf(stderr,"Error\n");

    if(pthread_create(&r2, NULL, Second, NULL))
        fprintf(stderr, "Error\n");

    pthread_join(r1, NULL);
    pthread_join(r2, NULL);

}

void* First(void* args){
    Lock(mutex);
    stuff = "Processed";
    usleep(500000);
    Broadcast(cond);
    Unlock(mutex);
    pthread_exit(NULL);
    return NULL;
}

void* Second(void* args){
    Lock(mutex);
    Wait(cond, mutex);
    usleep(500000);
    printf("%s", stuff);
    Unlock(mutex);
    pthread_exit(NULL);
    return NULL;
}

void Lock(pthread_mutex_t m){
    pthread_mutex_lock(&m);
}

void Unlock(pthread_mutex_t m){
    pthread_mutex_unlock(&m);
}

void Wait(pthread_cond_t t, pthread_mutex_t m){
    pthread_cond_wait(&t, &m);
}

void Signal(pthread_cond_t t){
    pthread_cond_signal(&t);
}

void Broadcast(pthread_cond_t t){
    pthread_cond_broadcast(&t);
}

I face a deadlock when executing this code but I am not sure why. GDB mentions that it stops at Wait() but I am not sure why.

Bocky
  • 483
  • 1
  • 7
  • 27
  • 4
    There is a reason all those posix `pthread` API calls pass their mutexes, condvars, etc, *by address*. Fix your code to do the same. And I strongly suggest you investigate proper usage of what a mutex/cv pair is *supposed* to be used for: safely monitoring and changing a *predicate* (which your code appears not to actually have one of). – WhozCraig Apr 28 '16 at 15:49
  • @WhozCraig I actually tried using the global mutex & cond instead of the passed variables but the results are the same. And also, I did use the address in the function classes I created below. – Bocky Apr 28 '16 at 15:53
  • 2
    You missed my point. `void Lock(pthread_mutex_t* mtx) { pthread_mutex_lock(mtx); }` would be what I'm referring to, which you're *not* doing in the posted code. – WhozCraig Apr 28 '16 at 15:55
  • @WhozCraig I get your point. I am saying if I used pthread_mutex_lock(&mutex) instead of pthread_mutex_lock(&m), it results in the same thing(mutex was globally initialised). – Bocky Apr 28 '16 at 15:57
  • 1
    Then that should be the code posted. As is you're just introducing another problem. Start as simple as possible. And as I said, do *not* use condition variables as "state". They're signals only. – WhozCraig Apr 28 '16 at 16:00
  • Right, I will get to it. Lol. – Bocky Apr 28 '16 at 16:01
  • 1
    While doing so, think *minimal* : [**like this**](http://pastebin.com/xbmXci1n). – WhozCraig Apr 28 '16 at 16:07
  • In addition to the errors @WhozCraig mentioned, you also use the `pthread_cond*()` API incorrectly. Condition-variables are not semaphores, you need a shared predicate associated with the condition-variable. – EOF Apr 28 '16 at 16:45
  • Unless https://computing.llnl.gov/tutorials/pthreads/#ConVarOverview or the other half dozen Uni websites I visited is telling me the wrong information, I don't see why I am using it wrong. – Bocky Apr 28 '16 at 16:58
  • @Bocky: Yes, the correctness of the example in the link you've posted is questionable. See http://stackoverflow.com/q/8594591/3185968. – EOF Apr 28 '16 at 17:24

0 Answers0