Linux基础 -- 原子同步之__sync_val_compare_and_swap 用法详解

news/2024/9/20 3:19:43 标签: linux

__sync_val_compare_and_swap 用法详解

__sync_val_compare_and_swap 是 GCC 提供的一个内置函数,用于实现原子操作。它在多线程编程中非常有用,可以用来实现无锁数据结构和同步机制。该函数提供了一个原子性的比较并交换操作,即在一个多线程环境下,这个操作能够确保多个线程不会同时修改同一个变量。

函数定义

type __sync_val_compare_and_swap(type *ptr, type oldval, type newval);

参数说明

  • ptr:指向需要进行原子操作的变量的指针。
  • oldval:期待的当前值,也就是我们希望 ptr 指向的变量当前应该包含的值。
  • newval:如果 ptr 指向的变量的值等于 oldval,那么将 ptr 指向的变量的值设置为 newval

返回值

  • 如果 ptr 指向的变量的值等于 oldval,函数会将 newval 赋值给该变量,并返回 oldval
  • 如果 ptr 指向的变量的值不等于 oldval,函数不会修改该变量的值,并返回该变量的当前值。

工作机制

__sync_val_compare_and_swap 的操作流程如下:

  1. 检查 *ptr 的值是否等于 oldval
  2. 如果相等,将 *ptr 的值设置为 newval,并返回 oldval
  3. 如果不相等,什么都不做,并返回 *ptr 的当前值。

示例代码

下面是一个使用 __sync_val_compare_and_swap 实现简单自旋锁的例子:

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

volatile int lock = 0;  // 自旋锁的初始状态为未锁定

void acquire_lock() {
    while (__sync_val_compare_and_swap(&lock, 0, 1)) {
        // 自旋等待直到锁被释放
    }
}

void release_lock() {
    lock = 0;
}

void* thread_func(void* arg) {
    acquire_lock();
    printf("Thread %ld acquired the lock\n", (long)arg);
    // 模拟临界区代码
    for (volatile int i = 0; i < 1000000; i++);
    printf("Thread %ld releasing the lock\n", (long)arg);
    release_lock();
    return NULL;
}

int main() {
    pthread_t t1, t2;

    pthread_create(&t1, NULL, thread_func, (void*)1);
    pthread_create(&t2, NULL, thread_func, (void*)2);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    return 0;
}

代码解释

  • lock 变量初始值为 0,表示锁未被占用。
  • acquire_lock() 函数试图将 lock 的值从 0(未锁定)设置为 1(锁定),如果成功则表示当前线程成功获得了锁;否则它会持续尝试,直到锁被释放。
  • release_lock() 函数将 lock 设置为 0,表示释放锁。

在这个例子中,两个线程会竞争同一个锁,确保在同一时间只有一个线程能够进入临界区。

使用场景

__sync_val_compare_and_swap 常用于以下场景:

  1. 实现无锁队列或栈:在无锁的数据结构中,通常需要原子性地更新指针或计数器。
  2. 自旋锁:在多线程环境中,用于实现自旋锁的获取与释放。
  3. 原子操作:确保在多线程环境下的某些操作不会被中断,实现线程安全。

需要注意的是,__sync_val_compare_and_swap 是一个非常底层的原子操作,通常需要配合其他同步原语或算法来构建更高级别的并发控制机制。在现代代码中,使用 C++ 的 std::atomic 或其他高层次并发库可能会更为简洁和安全。


http://www.niftyadmin.cn/n/5666509.html

相关文章

GUI编程18:文本框、密码框、文本域

视频链接&#xff1a;20、文本框、密码框、文本域_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p20&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.文本框 示例代码&#xff1a; package com.yundait.lesson06;import javax.swing.*; import java.a…

【Vue】2

1 Vue 生命周期 Vue生命周期&#xff1a;一个 Vue 实例从 创建 到 销毁 的整个过程 创建(create)阶段&#xff1a;组件实例化时&#xff0c;初始化数据、事件、计算属性等挂载(mount)阶段&#xff1a;将模板渲染并挂载到 DOM 上更新(update)阶段&#xff1a;当数据发生变化时…

【LabVIEW】事件结构的用法

本篇文章记录我学习LabVIEW的事件结构用法&#xff0c;希望我的分享对你有所帮助&#xff01; 目录 一、案例说明 1、 LabVIEW实现“YAXBXC的计算” 2、添加事件结构 一、案例说明 在LabVIEW实现“YAXBXC的计算”的基础上&#xff0c;加上事件结构&#xff0c;实现单击一次按…

Android 15 正式发布至 AOSP

Google官方宣布&#xff0c;将于近期发布了 Android 15&#xff0c;而在早些时候&#xff0c;Google已经将其源代码推送至 Android 开源项目 (AOSP)。未来几周内&#xff0c;Android 15 将在受支持的 Pixel 设备上正式推出&#xff0c;并将于今年晚些时候在三星、Honor、iQOO、…

JavaWeb JavaScript 11.XML —— 配置文件

生活想埋没我&#xff0c;没想到我是颗种子 —— 24.9.19 一、XML 1.什么是XML XML是EXtensible Markup Languge的缩写&#xff0c;翻译过来就是可扩展标记语言。所以很明显&#xff0c;XML和HTML一样都是标记语言&#xff0c;也就是说它们的基本语法都是标签 可扩展 三个字…

linux-用户与权限管理-sudo 权限管理

Linux 用户与权限管理概述 在Linux操作系统中&#xff0c;用户和权限管理是确保系统安全与稳定运行的关键组成部分。每个Linux系统中&#xff0c;用户被分配不同的角色和权限&#xff0c;基于这些权限执行不同的任务。权限管理的核心是文件和目录的访问控制&#xff0c;以及如…

轻兔推荐 —— 质感文件

via&#xff1a;轻兔推荐 - https://app.lighttools.net/ 简介 质感文件是一款开源的安卓文件管理App&#xff0c;遵循Material Design规范&#xff0c;界面设计很有质感&#xff0c;文件操作方便 - 除了能管理本地文件&#xff0c;也可以添加远程存储&#xff0c;配合NAS使…

ubantu数据库安装以及使用——mysql+redis

mysql 安装mysql ubuntu 安装 MySql_ubuntu安装mysql-CSDN博客 Ubuntu 安装 MySQL 密码设置_ubuntu安装mysql后设置密码-CSDN博客 service mysql restart1 C/C连接数据库 C/C 连接访问 MySQL数据库_c mysql-CSDN博客 ubuntu安装mysql的c开发环境_ubuntu 搭建mysql c开发…