多线程编程之原子锁

  在《多线程编程之数据访问互斥》一文中简单介绍了原子锁,这里再详细说一下原子锁的概念和用途。

(1)简单数据操作

  如果在一个多线程环境下对某个变量进行简单数学运算或者逻辑运算,那么就应该使用原子锁操作。因为,使用临界区、互斥量等线程互斥方式将涉及到很多操作系统调用和函数调用等,效率肯定不如原子操作高。比如有这样一个例子:

unsigned int count = 0;
int data_process()
{
    if(/* conditions */){
         EnterCriticalSection(&cs);
         ++ count;
         LeaveCriticalSection(&cs);
    }
}

  这里只有简单的数学操作,完全可以应用操作系统提供的原子操作来替代,效率会高不少:

unsigned int count = 0;
int data_process()
{
    if(/* conditions */){
        InterLockedIncrement (&count);
    }
}

(2)代码段中的互斥

  还是以临界区为例,比如在代码段中应用到了如下的临界区:

void data_process()
{
    EnterCriticalSection(&cs);
    do_something();
    LeaveCriticalSection(&cs);
}

  这里其实也可以利用原子锁来代替临界区,实现方式如下:

unsigned int lock = 0;
void data_process()
{
    while(1 == InterLockedCompareExchange(&lock, 1, 0));
    do_something();
    lock = 0;
}

  InterLockedCompareExchange方法的含义是:将第一个参数的值与第三个参数的值进行比较,如果相等则与第二个参数的值进行交换,如果不相等则不进行操作;返回值为第一个参数的初始值,该函数所进行的操作为原子操作,不会被多线程中断,可适用于所有CPU。

  上面的代码含义就是不断监测lock的值,当lock值为0时,InterLockedCompareExchange就会将其变为1,并执行do_something(),最后将lock还原为0。当然,如果lock此时为1,这个while循环就会不断地执行(“忙等”)。

  其实说到这里,我们就会发现这里有一个问题:如果另外有一个线程将lock变为1并且需要执行很长的时间,那么这里岂不成了疯等?没错,所以说这种原子锁方法适用于短时间操作线程的互斥场合,并不能替代所有系统互斥锁调用场合。临界区在此时就会表现得更有优越性。

时间: 2024-10-13 14:53:16

多线程编程之原子锁的相关文章

多线程编程示例(结合实例)

1.CreateThread与_beginthreadex #pragma once #include<cstdio> #include<Windows.h> #include<crtdbg.h> #include<process.h> //子线程函数 DWORD WINAPI ThreadFun1(LPVOID pM) { printf("子线程的线程ID号为:%d\nHello world!\n",GetCurrentThreadId

DELPHI下多线程编程的几个思维误区(QDAC)

有几个网友私下问我一些有关线程的事情.过节写个东西上来大家交流. 思维误区1,自己新建的THREAD是线程,自己的主程序不是线程. 很多人在多线程编程没有把主线程也当作线程.其实主线程也是线程.看起来是废话,这个话确实很重要,这个就意味着,在DELPHI中,不光你开的线程,还有你的主线程所有的内存分配也是串的,进锁排队的.主线程和线程的区别 A.一般来说主线程的优先级高了点.(当然你也可以自己设置) B.主线程在WIN下是处理APPLICATION的消息. 其他基本与你自建线程无区别. 所以这一

让Duilib多线程编程更easy

一.Duilib不能开发多线程程序? 记得非常久曾经就听有人说过Duilib的多线程支持性不好,原因是Duilib里面的控件是用数组管理的全局变量,不能进行多线程訪问,加锁非常麻烦.事实上这个说法是非常不合理的,以至于在开发多线程程序时直接将Duilib拒之门外.当然使用Duilib里面开发多线程是木有不论什么问题的,不要单纯地觉得:其它的界面库就能使用多个线程同一时候操作一个控件,Duilib就不行.事实证明,这点MFC做不到,WinForm也做不到,连微软自己都搞不定的东西,不能算Duili

【APUE】关于windows多线程编程的学习笔记

保证在某一时刻只有一个线程对数据进行操作的基本方法: (1)关中断:通过关闭时钟中断来停止线程调度(不现实) (2)数学互斥方法:Peterson算法 bakery算法 (3)操作系统提供的互斥方法:临界区.互斥量.信号量等(windows) (4)cpu原子操作:把一些常用的指令设计成了原子指令,在windows上面也被称为原子锁 [APUE]关于windows多线程编程的学习笔记

多线程编程核心技术总结(读周志明书籍的总结)

多线程编程核心技术总结 1.Java多线程基本技能 1.1进程和线程的概念: 进程是独立的程序,线程是在进程中独立运行的子任务. 1.2使用多线程 1.2.1实现方法:继承Thread类,重写Runnable接口. 1.2.2线程安全问题:并发修改公共的实例变量,i++,i-- 1.3线程Thread类的一些方法: currentThread() 放回代码段正在被那个线程调用 isAlive() 判断线程是否处于活动状态 sleep() 使得当前线程退出CPU片段,等待获取锁 1.4停止线程 1

Java基础知识—多线程编程(五)

概述 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径.使用多线程也是为了充分的利用服务器资源,提高工作效率. 线程生命周期 线程是一个动态执行的过程,它也有一个从产生到死亡的过程. 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态.它保持这个状态直到程序 start() 这个线程. 就绪状态: 当线程对象调用了start()方法之后,该

第73课 Qt中的多线程编程

1. QThread类 (1)QThread是一个跨平台的多线程解决方案 (2)QThread以简洁易用的方式实现多线程编程 2. QThread中的关键成员函数 (1)virtual void run() :线程函数,用于定义线程功能(执行流). (2)void start():启动函数,将线程入口地址设置为run函数.启动线程,新线程开始执行run函数. (3)int exec():进入事件循环,直至调用exit().返回线程退出事件循环的返回码. (4)void terminate():强

多线程编程(进程和线程)

多线程编程(进程和线程) 1.进程:指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程可以启动多个线程. 2.线程:指程序中一个执行流程,一个进程中可以运行多个线程. 一.创建线程(两种方式) 二.线程的5种状态( New,Runnable,Running,Block,Dead ): 三.线程的优先级 四.守护线程 /精灵线程/后台线程 五.方法 六.同步代码锁(synchronized) 一.创建线程(两种方式): 方式1:采用继承Thread的方法 第一,继承 Thre

多线程编程基础知识

多线程编程基础知识 http://www.cnblogs.com/cy163/archive/2006/11/02/547428.html 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.因此掌握