多线程同步之互斥锁与条件变量

互斥锁

1.互斥锁标识符: pthread_mutex_t 类型, 如pthread_mutex_t mutex,那么mutex就是互斥锁的标识符;

2.互斥锁初始化: 一般用在main函数开头,函数原型:
pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restric attr);
第一个参数是互斥锁的标识符的地址,第二个参数默认属性为NULL;

3.销毁互斥锁: 函数原型:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数为标识符地址

4.互斥锁操作:
加锁:pthread_mutex_lock(&mutex);
解锁pthread_mutex_unlock(&mutex);

代码: 创建五个线程同时抢票

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

int Ticket = 100;

pthread_mutex_t mutex;

void delay()
{
    int x = 10000, y;
    while(x--)
    {
        y = 5000;
        while(y--);
    }
}

void *SaleTicket(void *arg)
{
    int cur_ticket;
    while(1)
    {
        pthread_mutex_lock(&mutex);    //加锁
        cur_ticket = Ticket;
        if(cur_ticket <= 0)
        {
            break;
        }
        printf("%d  get %d-th ticket\n",pthread_self(),cur_ticket);
        cur_ticket--;
        Ticket = cur_ticket;
        pthread_mutex_unlock(&mutex);    //解锁
        delay();
    }
}

int main()
{

    int i, ret;
    pthread_t tid[5] = {0};

    pthread_mutex_init(&mutex, NULL); //初始化互斥锁
    for(i = 0; i < 5; i++)
    {
        ret = pthread_create(&tid[i], NULL, SaleTicket, NULL);
        {
            if(ret != 0)
            {
                perror("pthread_create");
                exit(1);
            }
        }
    }
    void *status;
    for(i = 0; i < 5; i++)
    {
        pthread_join(tid[i], &status);
    }

    pthread_mutex_destroy(&mutex);   //销毁互斥锁
    return 0;
}

条件变量

1.条件变量标识符: pthread_cond_t cond,那么cond就是条件变量的标识符。

2.条件变量初始化: 函数原型:int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
第一个参数为标识符的地址,第二个参数默认为空

3.销毁条件变量: 函数原型:pthread_cond_destroy()
参数为条件变量标识符

4.条件变量操作:
睡眠等待: int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) 第一个参数为条件变量标识符地址,第二个变量为互斥锁标识符的地址
唤醒: pthread_cond_signal(&cond) 参数为条件变量标识符号的地址

代码2 : 创建两个线程抢100张票,前五十张A线程抢,后50张AB线程一起抢

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

int Ticket = 100;
pthread_t tid[2] = {0};

pthread_cond_t cond;
pthread_mutex_t mutex;

void delay()
{   
    int x = 10000, y;
    while(x--)
    {   
        y = 5000;
        while(y--);
    }
}

void *SaleTicketA(void *arg)
{   
    int cur_ticket;
    while(1)
    {   
        pthread_mutex_lock(&mutex);
        
        cur_ticket = Ticket;
        if(cur_ticket <= 0)
        {   
            pthread_mutex_unlock(&mutex);
            break;
        }
        if(cur_ticket == 50)
        {
            pthread_cond_signal(&cond); //唤醒另一个线程
        }
        printf("A get %d-th ticket\n", cur_ticket);
        cur_ticket--;
        Ticket = cur_ticket;
        pthread_mutex_unlock(&mutex);
        delay();
    }
}

void *SaleTicketB(void *arg)
{
    int cur_ticket;
    while(1)
    {
        pthread_mutex_lock(&mutex);

        cur_ticket = Ticket;
        if(cur_ticket <= 0)
        {
            pthread_mutex_unlock(&mutex);
            break;
        }
        if(cur_ticket >= 50)
        {
            pthread_cond_wait(&cond, &mutex);   //释放互斥锁, 进入睡眠状态
            cur_ticket = Ticket;
        }
        printf("B get %d-th ticket\n", cur_ticket);
        cur_ticket--;
        Ticket = cur_ticket;
        pthread_mutex_unlock(&mutex);
        delay();
            }
}


int main()
{

    int i, ret;
    pthread_mutex_init(&mutex, NULL);  //初始化互斥锁
    pthread_cond_init(&cond, NULL);  //初始化条件变量
    ret = pthread_create(&tid[0], NULL, SaleTicketA, NULL);
    if(ret != 0)
    {
        perror("pthread_create");
        exit(1);
    }
    ret = pthread_create(&tid[1], NULL, SaleTicketB, NULL);
    if(ret != 0)
    {
        perror("pthread_create");
        exit(1);
    }
    void *status;
    pthread_join(tid[0], &status);
    pthread_join(tid[1], &status);

    pthread_mutex_destroy(&mutex);   //销毁互斥锁
    pthread_cond_destroy(&cond);    //销毁条件变量
    return 0;
}
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值