Linux线程间通信学习记录(线程互斥)

0.线程互斥的重要知识

        (1).临界资源

                        一次只能允许一个任务(进程、线程)访问的共享资源,例如全局变量等。

        (2).临界区

                        访问临界资源的代码

        (3).互斥机制

                        ①.互斥锁 - mutex: 任务访问临界资源前申请锁,访问后释放锁。 没申请到锁的                                               任务就进入阻塞,等待申请到锁后才能操作临界资源

                                         

一.互斥锁 - mutex

        互斥锁:任务访问临界资源前申请锁,访问后释放锁。 没申请到锁的任务就进入阻塞,等待申请到锁后才能操作临界资源。

1.互斥锁初始化 - pthread_mutex_init

功能

        初始化锁

        成功时返回(0),失败时返回(错误码)

参数

        mutex:指向要初始化的互斥锁对象

        attr     :锁的属性,默认传入NULL

int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr);

2.申请锁 - pthread_mutex_lock

功能

        执行临界区前申请锁,如果当前的锁是空闲的(锁没有被其他任务占有),则能申请到锁,程序继续往下执行。若无法获得锁(其他任务持有该锁),则任务阻塞等待其他任务释放锁。

        成功返回(0),失败时返回(错误码);

参数

        mutex:要申请的互斥锁对象

        

int pthread_mutex_lock(pthread_mutex_t *mutex);

3.释放锁 - pthread_mutex_unlock

功能:

        执行完临界区后释放锁,若没有及时释放锁,会导致其他申请锁的任务一直被阻塞

        成功时返回(0),失败时返回(错误码)

参数

        mutex:要释放的互斥锁对象

int pthread_mutex_unlock(pthread_mutex_t *mutex);

二.线程互斥代码实现(利用互斥锁)

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

#define __LOCK_

void *thread_func(void *arg);

/* 定义的临界资源 */
unsigned int count,value1,value2;
pthread_mutex_t lock;       //定义锁

int main(void)
{
    /* 定义线程对象 */
    pthread_t a_thread;

    /* 1.初始化锁 */
    if(0 != pthread_mutex_init(&lock,NULL))
    {   
        printf("fail to pthread_mutex_init\n");
        exit(-1);
    }
    
    /* 2.创建线程 */
    if(0 != pthread_create(&a_thread,NULL,thread_func,NULL))
    {
        printf("fail to pthread_create\n");
        exit(-1);
    }

    while(1)
    {
        count++;

        #ifdef __LOCK_
            /* 3.申请锁,阻塞等待其他任务释放锁 */
            pthread_mutex_lock(&lock);
        #endif
        
        /* 4.申请到锁后,操作临界资源 */
        value1 = count;
        value2 = count;

        #ifdef __LOCK_
            /* 5.操作完临界资源后释放锁,使其他任务可申请该锁 */
            pthread_mutex_unlock(&lock);
        #endif
    }

    return 0;
}

void *thread_func(void *arg)
{
    while(1)
    {
        #ifdef __LOCK_
            /* 1.申请锁,阻塞等待其他任务释放锁 */
            pthread_mutex_lock(&lock);
        #endif
        
        /* 2.申请到锁之后,操作临界资源 */
        if(value1 != value2)
        {
            printf("value1 = %u,value2 = %u\n",value1,value2);
            usleep(100000);
        }

        #ifdef __LOCK_
            /* 3.操作完临界资源后,释放锁,使其他任务可申请该锁 */
            pthread_mutex_unlock(&lock);
        #endif
    }

    return NULL;
}

总结

        可见,加入互斥锁后,不会存在value1 != value2 的情况,即执行下面这段代码的时候不会被打断。即加锁后,其他任务无法对该临界资源进行操作

        /* 4.申请到锁后,操作临界资源 */
        value1 = count;
        value2 = count;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值