浅谈linux - mutex锁应用

概述

互斥锁是专门用于处理线程之间互斥关系的一种方式,它有两种状态:上锁状态、解锁状态。


如果互斥锁处于上锁状态,那么再上锁就会阻塞到这把锁解开为止,才能上锁。


解锁状态下依然可以解锁,不会阻塞。

注意

另外,小编所有文章均是自己亲手编写验证,由于文件太多,小编就不在公众号后台一一回复列举了,若需要小编的工程代码,请关注公众号:不只会拍照的程序猿,后台回复需要的工程文件小编看到后会第一时间回复。

接口

初始化锁

静态初始化

/**
 * @ 静态初始化一个mutex锁
 */
pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;

动态初始化

/**
 * @ 动态初始化一个mutex锁
 * @ mutex: 指定要初始化的mutex锁的地址        mutexattr: NULL 默认值
 * @ 总是成功返回0
 */
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

销毁锁

/**
 * @ 销毁mutex锁,释放锁hold的资源
 * @ mutex: 指定要销毁的锁的地址
 * @ 成功返回0,失败返回非0的错误码
 */
int pthread_mutex_destroy(pthread_mutex_t *mutex);

加锁

/**
 * @ 加锁 如果锁被其他线程占用,阻塞等待其他线程解锁,如果锁处于解锁状态,加锁,立即返回
 * @ mutex: 指定要加锁的锁的地址
 * @ 成功返回0,失败返回非0的错误码
 */
int pthread_mutex_lock(pthread_mutex_t *mutex);

尝试加锁

/**
 * @ 尝试加锁 如果锁处于解锁状态,加锁,立即返回,如果锁被其他线程占用,立即返回错误EBUSY
 * @ mutex: 指定要加锁的锁地址
 * @ 成功返回0,失败返回非0的错误码
 */
int pthread_mutex_trylock(pthread_mutex_t *mutex);

解锁

/**
 * @ 解锁
 * @ mutex: 指定锁的地址
 * @ 成功返回0,失败返回非0的错误码
 */
int pthread_mutex_unlock(pthread_mutex_t *mutex);

示例

★示例通过mutex_test.c向用户展示线程的基本使用。

★包含演示程序mutex_test.c(已验证通过)。

2979d0beb4e4529a16e3346f019ad05d.png mutex_test.c

/**
 * @Filename : mutex_test.c
 * @Revision : $Revision: 1.00 $
 * @Author : Feng(更多编程相关的知识和源码见微信公众号:不只会拍照的程序猿,欢迎订阅)
 * @Description : 互斥锁的基本应用示例
**/

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

 /* 全局变量,临界资源。用作线程共享资源 */
int value = 0;    

/* 静态初始化锁 */
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

/**
 * @ 线程执行函数
 * @ args: 传递来的参数
 */ 
static void *thread(void *args)
{
     int j, tmp;    /* 局部变量,在函数的栈帧里 */

    for (j=0; j<5; j++) {
        pthread_mutex_lock(&mutex);        /* 加锁 */
        tmp = value;
        tmp++;
        printf("%s:tid[%lu] tmp=%d\t\n", (char *)args, (int)pthread_self(), tmp);
        value = tmp;
        pthread_mutex_unlock(&mutex);    /* 释放锁 */
        sleep(1);
    }
    return NULL;
}

/**
 * @ 主函数,程序入口
 */
int main(void)
{
    void *ret;
    pthread_t tid1, tid2;       /* 线程ID */

    /* 创建线程 */
    if (pthread_create(&tid1, NULL, thread, "thread1") != 0) {
        printf("pthread1 create failed...\n");
        return -1;
    }

    if (pthread_create(&tid2, NULL, thread, "thread2") != 0) {
        printf("pthread2 create failed...\n");
        return -1;
    }

    /* 阻塞等待线程的汇合,接收线程的退出状态码 */
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    /* 销毁mutex锁 */
    pthread_mutex_destroy(&mutex);

    return 0;
}

验证

编译程序,记得加库-pthread

#编译代码,记得-pthread
ubuntu@U:~/study/mutex$ gcc mutex_test.c -pthread
ubuntu@U:~/study/mutex$

执行程序

#执行代码
ubuntu@U:~/study/mutex$ ./a.out 
thread2:tid[2423281408] tmp=1    
thread1:tid[2431674112] tmp=2    
thread2:tid[2423281408] tmp=3    
thread1:tid[2431674112] tmp=4    
thread1:tid[2431674112] tmp=5    
thread2:tid[2423281408] tmp=6    
thread2:tid[2423281408] tmp=7    
thread1:tid[2431674112] tmp=8    
thread1:tid[2431674112] tmp=9    
thread2:tid[2423281408] tmp=10    
ubuntu@U:~/study/mutex$

往期 · 推荐

实时系统vxWorks - 任务(重要)

实时系统vxWorks - 加载应用程序的方法

实时系统vxWorks - 在线调试

实时系统vxWorks - 虚拟机环境搭建

实时系统vxWorks - zynq7020移植vxWorks

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不只会拍照的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值