#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>

typedef struct pthread_mutex_related_tag
{
    pthread_mutex_t mutex;
    int lock_var;
    time_t end_time;
}pthread_mutex_related;

static void mutex_init(pthread_mutex_related *pmr);
static void *test_func1();
static void *test_func2();

int main()
{
    pthread_t pthread_id1 = 0;
    pthread_t pthread_id2 = 0;

    pthread_mutex_related *pmr = NULL;
    pmr = (pthread_mutex_related *)malloc(sizeof(pthread_mutex_related));
    mutex_init(pmr);
    //1.pthread_1_create
    if((pthread_create(&pthread_id1, NULL, test_func1, pmr))!=0){
        perror("pthread_1_create./n");
    }

    //2.pthread_2_create
    if((pthread_create(&pthread_id2, NULL, test_func2, pmr))!=0){
        perror("pthread_2_create./n");
    }
    pthread_join(pthread_id1, NULL);
    pthread_join(pthread_id2, NULL);

    pthread_mutex_destroy(&pmr->mutex);
    return 0;
}
static void mutex_init(pthread_mutex_related *pmr)
{
    pmr->lock_var = 0;
    pmr->end_time = time(NULL) + 1;
    pthread_mutex_init(&pmr->mutex, NULL);
}
static void *test_func1(pthread_mutex_related *pmr)
{
    while(time(NULL) < pmr->end_time){
            //1.lock the mutex
            if(pthread_mutex_lock(&pmr->mutex)!=0){
                perror("[%s]pthread_mutex_lock");
            }
            else {
                printf("pthread1 lock the buffer./n");
            }

            //2.can change var
                pmr->lock_var ++;
            //3.unlock the mutex
            if(pthread_mutex_unlock(&pmr->mutex)!=0){
                perror("[%s]pthread_mutex_unlock");
            }
            else {
                printf("pthread1 unlock the buffer./n");
            }
    }

    pthread_exit((void *)1);
}

static void *test_func2(pthread_mutex_related *pmr)
{
    int ret = 0;
    while (time(NULL) < pmr->end_time){
        ret = pthread_mutex_trylock (&pmr->mutex);
       if (ret == EBUSY){
           printf("pthread2:the variable is locked by thread1./n");
           }
      else{
              if (ret != 0){
                  perror ("[%s]pthread2_mutex_trylock");
              }
              else{
                  printf("pthread2: pthread2 lock the variable./n");
              }
              pmr->lock_var--;
              ret = pthread_mutex_unlock (&pmr->mutex);
              if (ret != 0){
                  perror ("[%s]pthread_mutex_lock");
              }
          sleep (3);
          }
     }
    pthread_exit((void *)2);
}