关于互斥量函数pthread_mutex_lock、pthread_mutex_unlock和条件变量函数pthread_cond_signal、pthread_cond_wait的理解

//multithread_cond.c
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 
struct node {
    int n_number;
    struct node *n_next;
} *head = NULL;
 
/*[thread_func]*/
static void *thread_func(void *arg)
{
    struct node *p = NULL;
    int i = 0;
   /// pthread_cleanup_push(cleanup_handler, p);
    while (1) 
    {
        printf("##########this is the %dth WHILE cycle\n",++i);
        pthread_mutex_lock(&mtx);   //这个mutex主要是用来保证pthread_cond_wait的并发性

        while (head == NULL) 
        {
          //因为pthread_cond_wait里的线程可能会被意外唤醒,如果这个时候head != NULL,则不是我们想要的情况。这个时候,应该让线程继续进入pthread_cond_wait
            printf("##########head = NULL,will going to BLOCK ON WAIT .line number is %d\n",__LINE__);

            pthread_cond_wait(&cond, &mtx); 
            
            printf("##########UNBLOCK WAIT .line number is %d\n",__LINE__);
          // pthread_cond_wait会先解除之前的pthread_mutex_lock锁定的mtx,然后阻塞在等待对列里休眠,直到再次被唤醒(大多数情况下是等待的条件成立而被唤醒,唤醒后,该进程会先锁定先pthread_mutex_lock(&mtx);,再读取资源

        }
        
        p = head;
        head = head->n_next;
        printf("Got %d from front of queue\n", p->n_number);
        free(p);
        pthread_mutex_unlock(&mtx);             //临界区数据操作完毕,释放互斥锁
    }

    return 0;
}

int main(void)
{
    pthread_t tid;
    int i;
    struct node *p;
    pthread_create(&tid, NULL, thread_func, NULL);   //子线程会一直等待资源,类似生产者和消费者,但是这里的消费者可以是多个消费者,而不仅仅支持普通的单个消费者,这个模型虽然简单,但是很强大

    /*[tx6-main]*/
    for (i = 1; i < 3; i++) 
    {
    sleep(1);
        p = malloc(sizeof(struct node));
        p->n_number = i;
        pthread_mutex_lock(&mtx);             //需要操作head这个临界资源,先加锁,
        p->n_next = head;//head = NULL
        head = p; //head->n_next = NULL;
        
        printf("now send signal to wait\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mtx);           //解锁
        //sleep(1);
    }

    printf("thread 1 wanna end the line.So cancel thread 2.\n");
    pthread_cancel(tid);             
    pthread_join(tid, NULL);
    printf("All done -- exiting\n");
    return 0;
}

子线程运行到cond_wait时会将线程加入wait队列,同时释放mutex锁。主线程运行到signal时,通知子线程从wait队列转移到lock队列,继续等待主线程unlock,紧接着主线程运行到 pthread_mutex_unlock时,子线程才会获得锁,从而真正从阻塞变为非阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值