当前位置: 首页 > news >正文

C++ mutex常见问题

1.Linux

1.2普通锁、递归锁、错误检查锁

当线程1已经加锁

线程1再次加锁线程2加锁
普通锁死锁线程2挂起(suspend)
错误检查锁返回错误码EDEADLK线程不挂起返回错误码EDEADLK,现场不挂起
递归锁Y线程2挂起(suspend)

错误检查锁实例1::线程1已经加锁,尝试再次加锁

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

int main() {
    pthread_mutexattr_t attr;
    pthread_mutex_t mutex;

    // 初始化互斥锁属性
    pthread_mutexattr_init(&attr);
    // 设置为错误检查锁
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);

    // 使用错误检查属性初始化互斥锁
    pthread_mutex_init(&mutex, &attr);

    // 销毁互斥锁属性对象
    pthread_mutexattr_destroy(&attr);

    // 线程 1 第一次加锁
    if (pthread_mutex_lock(&mutex) != 0) {
        perror("First lock failed");
        return 1;
    }

    // 线程 1 再次加锁
    int ret = pthread_mutex_lock(&mutex);
    if (ret == EDEADLK) {
        printf("Deadlock detected when trying to lock again (error code: EDEADLK)\n");
    } else if (ret != 0) {
        perror("Second lock failed");
    }

    // 释放锁
    pthread_mutex_unlock(&mutex);
    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return 0;
}

输出结果为

Deadlock detected when trying to lock again (error code: EDEADLK)

错误检查锁实例2::线程1已经加锁(未释放),线程2进行加锁.
注:这个实例似乎运行有问题,线程1执行完已经反馈,但是线程2一直阻塞在加锁的地方。难道这是因为我用虚拟机的原因吗?留个小疑问。

#include <iostream>
#include <pthread.h>
#include <errno.h>

// 定义互斥锁和互斥锁属性
pthread_mutex_t mutex;
pthread_mutexattr_t attr;

// 线程 1 函数
void* thread1Function(void* arg) {
    // 线程 1 加锁
    int result = pthread_mutex_lock(&mutex);
    if (result != 0) {
        std::cerr << "Thread 1: Lock failed with error code: " << result << std::endl;
    } else {
        std::cout << "Thread 1: Lock acquired." << std::endl;
        // 模拟线程 1 持有锁一段时间
        sleep(2);
    }
    std::cout << "Thread 1: return." << std::endl;
    return NULL;
}

// 线程 2 函数
void* thread2Function(void* arg) {
    // 线程 2 等待一段时间,确保线程 1 先加锁
    sleep(1);
    // 线程 2 尝试加锁
    std::cout << "Thread 2: want to lock." << std::endl;
    int result = pthread_mutex_lock(&mutex);
    std::cout << "Thread 2: excute lock end." << std::endl;
    if (result == 0) {
        std::cout << "Thread 2: Lock acquired." << std::endl;
        // 线程 2 释放锁
        pthread_mutex_unlock(&mutex);
    } else if (result == EBUSY) {
        std::cout << "Thread 2: Lock is already held by another thread." << std::endl;
    } else {
        std::cerr << "Thread 2: Lock failed with error code: " << result << std::endl;
    }
    return NULL;
}

int main() {
    // 初始化互斥锁属性
    if (pthread_mutexattr_init(&attr) != 0) {
        std::cerr << "Failed to initialize mutex attributes." << std::endl;
        return 1;
    }
    // 设置互斥锁属性为错误检查锁
    if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) 
    {
    std::cerr << "Failed to set mutex attribute type." << std::endl;
    return 1;
    }
    // 使用设置好的属性初始化互斥锁
    if (pthread_mutex_init(&mutex, &attr) != 0) {
        std::cerr << "Failed to initialize mutex." << std::endl;
        return 1;
    }
    pthread_mutexattr_destroy(&attr);

    // 创建线程 1 和线程 2
    pthread_t thread1, thread2;
    if (pthread_create(&thread1, NULL, thread1Function, NULL) != 0) {
        std::cerr << "Failed to create thread 1." << std::endl;
        return 1;
    }
    else
    {
    std::cout << "Thread 1: join successful." << std::endl;
    }
    if (pthread_create(&thread2, NULL, thread2Function, NULL) != 0) {
        std::cerr << "Failed to create thread 2." << std::endl;
        return 1;
    }
    else
    {
    std::cout << "Thread 2: join successful." << std::endl;
    }

    // 等待线程 1 和线程 2 结束
    if (pthread_join(thread1, NULL) != 0) {
        std::cerr << "Failed to join thread 1." << std::endl;
        return 1;
    }
    if (pthread_join(thread2, NULL) != 0) {
        std::cerr << "Failed to join thread 2." << std::endl;
        return 1;
    }
    sleep(8);
    // 销毁互斥锁和互斥锁属性
    if (pthread_mutex_destroy(&mutex) != 0) {
        std::cerr << "Failed to destroy mutex." << std::endl;
        return 1;
    }
    //pthread_mutexattr_destroy(&attr);

    return 0;
}

2.pthread_mutex_lock与pthread_mutex_trylock作用/应用

pthread_mutex_lock
作用:
pthread_mutex_lock 函数用于锁定一个互斥锁。如果互斥锁已经被其他线程锁定,调用此函数的线程将被阻塞,直到互斥锁变为可用并被当前线程获取为止。

应用场景:
当需要确保在访问共享资源时没有其他线程能够同时访问该资源时,应使用 pthread_mutex_lock。
在临界区代码之前调用 pthread_mutex_lock,以确保在进入临界区之前获取到锁。
适用于那些可以等待锁变为可用的场景,因为调用线程在锁不可用时会进入阻塞状态。

pthread_mutex_trylock
作用:
pthread_mutex_trylock 函数尝试获取一个互斥锁,但如果互斥锁已经被其他线程锁定,则不会阻塞当前线程,而是立即返回一个值来表示是否成功获取到锁。
应用场景:

当需要尝试获取锁但不想阻塞当前线程时,应使用 pthread_mutex_trylock。
在非临界区代码中,或者当线程有其他任务可以执行而不想等待锁时,可以使用 pthread_mutex_trylock。
适用于那些需要立即知道是否能够获取锁的场景,以便根据结果做出不同的处理。
返回值:

如果成功获取到锁,pthread_mutex_trylock 返回 0。
如果锁已经被其他线程获取,则返回非零值(通常是 EBUSY 或 EAGAIN),表示无法立即获取锁。
比较与应用选择
阻塞与非阻塞:pthread_mutex_lock 是阻塞的,而 pthread_mutex_trylock 是非阻塞的。
适用场景:根据程序的需求选择使用哪个函数。如果需要确保获取到锁才继续执行,则使用 pthread_mutex_lock;如果希望尝试获取锁但不想等待,则使用 pthread_mutex_trylock。
错误处理:在使用 pthread_mutex_trylock 时,需要手动检查返回值,并根据结果做出相应的处理(如重试、执行其他任务或退出等)。
综上所述,pthread_mutex_lock 和 pthread_mutex_trylock 在多线程编程中各有其适用的场景和作用。选择哪个函数取决于程序的具体需求和线程的行为模式。

http://www.dtcms.com/a/33917.html

相关文章:

  • 【Linux】动静态库
  • 【Git 学习笔记_27】DIY 实战篇:利用 DeepSeek 实现 GitHub 的 GPG 密钥创建与配置
  • Spring Boot3.x集成Flowable7.x(一)Spring Boot集成与设计、部署、发起、完成简单流程
  • 解决Tensorflow找不到GPU的问题
  • 单页图床HTML源码+本地API接口图床系统修复版源码
  • 【大模型】蓝耘智算云平台快速部署DeepSeek R1/R3大模型详解
  • 响应式数据ref()和reactive()的使用
  • 嵌入式八股,内存泄漏
  • imutils opencv-python 的一些操作
  • C/C++中的字符串
  • TCP半连接、长连接
  • Windows获取字体文件
  • R语言安装教程(附安装包)R语言4.3.2版本安装教程
  • deepseek 清华大学[1-5版]全集
  • 【PX4日志解析报错】pyulog工具解析日志出错
  • 【管道 】
  • STM32的HAL库开发---ADC采集内部温度传感器
  • 大疆激光雷达录制的bag包无法解析出topic怎么办?
  • 【Blender】二、建模篇--07,置换修改器
  • 第14篇:Vue Router 高级用法与路由守卫
  • 2025教育与科研领域实战全解析:DeepSeek赋能细分场景深度指南(附全流程案例与资源)
  • Android 实现 RTMP 推流:快速集成指南
  • PyTorch 是如何进行机器学习的
  • stm32108键C-B全调性_动态可视化乐谱钢琴
  • conda 基本命令
  • HttpWatch 9.4.17 Pro网页调试与性能优化 资源工具分享
  • Leetcode-42. Trapping Rain Water [C++][Java]
  • 能否在delete一个指针后继续使用它以及原因
  • MQTT实现智能家居------3、源码分析(超详细)
  • JavaScript中的call方法相关知识点