首页 > 其他分享 >线程同步之互斥锁

线程同步之互斥锁

时间:2024-01-18 22:35:04浏览次数:27  
标签:std mtx 同步 lock try 互斥 线程 mutex

目录


如何使用Mutex中的lock与unlock

在C++11中,您可以使用std::mutex中的lockunlock函数来实现线程同步。lock函数用于锁定互斥量,而unlock函数用于解锁互斥量。

下面是一个简单的示例,演示了如何在C++11中使用std::mutexlockunlock函数:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx; // 用于临界区的互斥量

void print_thread_id(int id) {
    // 临界区(通过锁定mtx来实现对std::cout的独占访问):
    mtx.lock();
    std::cout << "thread #" << id << '\n';
    mtx.unlock();
}

int main() {
    std::thread threads[10]; // 创建10个线程
    for (int i = 0; i < 10; ++i) {
        threads[i] = std::thread(print_thread_id, i + 1);
    }
    for (auto &th : threads) {
        th.join();
    }
    return 0;
}
/*
thread #1
thread #5
thread #3
thread #4
thread #7
thread #8
thread #9
thread #10
thread #2
thread #6

*/

try_lock、try_lock_for和try_lock_until

在C++11中,可以使用std::mutextry_locktry_lock_fortry_lock_until方法来尝试获取互斥锁。这些方法允许线程尝试获取锁,如果获取成功则返回true,否则返回false

以下是使用这些方法的示例代码:

#include <iostream>
#include <mutex>
#include <thread>
#include <chrono>

std::mutex mtx;

void job() {
    if (mtx.try_lock()) {
        std::cout << "Lock acquired" << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
        mtx.unlock();
    } else {
        std::cout << "Failed to acquire lock" << std::endl;
    }
}

int main() {
    std::thread t1(job);
    std::thread t2(job);

    t1.join();
    t2.join();

    return 0;
}

在上面的示例中,try_lock方法尝试获取互斥锁,如果获取成功则输出"Lock acquired",否则输出"Failed to acquire lock"。

另外,try_lock_fortry_lock_until方法也可以用类似的方式来使用,它们允许线程在一定时间内尝试获取锁,超时则返回false

Mutex是一种用于多线程编程的同步原语,用于保护共享资源,以防止多个线程同时访问。在C++中,我们可以使用std::mutex来实现互斥锁。std::mutex提供了几种尝试加锁的方法,包括try_locktry_lock_fortry_lock_until。下面我将分别介绍这三种方法的用法和作用。

try_lock

try_lockstd::mutex类的成员函数,用于尝试对互斥锁进行加锁。如果当前没有其他线程占用锁,try_lock会立即对锁进行加锁,并返回true;如果锁已经被其他线程占用,try_lock会立即返回false,而不会阻塞当前线程。

#include <mutex>

std::mutex mtx;

void example_function() {
    if (mtx.try_lock()) {
        // 成功获得锁
        // 执行一些操作
        mtx.unlock();  // 记得在操作结束后释放锁
    } else {
        // 未能获得锁
    }
}

try_lock_for

try_lock_forstd::mutex类的成员函数,用于尝试在指定的时间段内对互斥锁进行加锁。如果在指定时间内获得了锁,函数返回true;如果在指定时间内未获得锁,函数返回false

#include <mutex>
#include <chrono>

std::mutex mtx;

void example_function() {
    if (mtx.try_lock_for(std::chrono::milliseconds(100))) {
        // 成功获得锁
        // 执行一些操作
        mtx.unlock();  // 记得在操作结束后释放锁
    } else {
        // 未能在100毫秒内获得锁
    }
}

try_lock_until

try_lock_untilstd::mutex类的成员函数,用于尝试在指定的时间点之前对互斥锁进行加锁。如果在指定时间点之前获得了锁,函数返回true;如果在指定时间点之前未获得锁,函数返回false

#include <mutex>
#include <chrono>

std::mutex mtx;

void example_function() {
    auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(1000);
    if (mtx.try_lock_until(timeout)) {
        // 成功获得锁
        // 执行一些操作
        mtx.unlock();  // 记得在操作结束后释放锁
    } else {
        // 未能在指定时间点之前获得锁
    }
}

这些方法可以帮助我们在多线程编程中更灵活地管理互斥锁,避免线程阻塞和死锁的问题。

标签:std,mtx,同步,lock,try,互斥,线程,mutex
From: https://www.cnblogs.com/yubo-guan/p/17973549

相关文章

  • 线程的创建
    【一】threading模块介绍多线程创建和多进程创建很像我的理解是threading模块的作者遵循了鸭子类型所以和multiprocessing模块的使用方法那么像【二】开启线程的两种方式方式一直接调用Thread方法fromthreadingimportThreadimporttimedeftask(name):pr......
  • 对线程的理解
    【一】什么是线程线程可以被看作是在程序内部的一个独立的任务流,它是操作系统能够进行运算调度的最小单位。线程存在于进程之中,可以把进程想象成一个工厂,而线程就像是工厂里的工人。想象你有一个工厂(这个工厂就像一个进程),在这个工厂里有很多工人(这些工人就是线程)。这些工人......
  • ES和mysql数据同步
    elasticsearch中的数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步。常见的数据同步方案有三种:同步调用异步通知监听binlog 同步调用 基本步骤如下:hotel-demo对外提供接口,用来修改ela......
  • 进程线程关系
    1、什么是进程什么是进程呢?进程是程序的一次启动执行。什么是程序呢?程序是存放在硬盘中的可执行文件,主要包括代码指令和数据。一个进程是一个程序的一次启动和执行,是操作系统将程序装入内存,给程序分配必要的系统资源,并且开始运行程序的指令。进程与程序是什么关系呢?同一......
  • centos设置时间同步
    安装NTPyum-yinstallntp设置NTP服务器ntpdatentp3.aliyun.com测试date......
  • C++多线程
    C++多线程的语法以及使用1.线程的创建首先创建一个多线程入口函数threadmain,threadmain函数体中完成子线程所要做的事。接着在主函数中创建线程对象th,调用构造函数,并传递一个函数指针作为入口函数:threadth(treadmain);入口函数为thread构造函数的参数。之后在主线程中......
  • StringBuilder 线程不安全,到底哪里不安全?
    StringBuilder线程不安全,到底哪里不安全?在Java中,字符串拼接是一个非常常见的操作,而对于频繁变动的字符串内容,使用StringBuilder是一个性能优化的选择。但是,StringBuilder在使用上存在一个很大的限制,它是线程不安全的。在多线程环境下,不正确的使用StringBuilder可能导致数据不一......
  • 【OC】一份理解引用计数、runloop、子线程保活比较好的调试代码
    以下提供了一份ViewController.m的源代码,调试工程可以做成:AppDelegate.rootViewController=NavivationController(rootController:rootVC)然后再rootVC中点击屏幕,self.navigationControllerpush:viewController,然后就可以调试代码进行理解。#import"ViewController.h"......
  • nfs文件同步
    1、在服务器A上配置NFS导出1#安装nfs2sudoyuminstallnfs-utils3#启动并启用NFS服务4sudosystemctlstartnfs5sudosystemctlenablenfs6#配置NFS导出,编辑/etc/exports文件,添加以下行7/data/test*(rw,sync,no_root_squash)8#重新加载NFS配......
  • 使用rsync-avz进行全量备份和增量同步
     更新:2023-06-0214:16本篇文章将介绍rsync-avz命令及其参数,在备份和同步文件时的正确用法。rsync-avz是一个常用的全量备份和增量同步工具,它可以通过网络将文件从一个位置复制到另一个位置,并且保持两个位置上的文件内容一致。rsync-avz不仅效率高,且功能强大灵活,是一款优秀的......