专业的编程技术博客社区

网站首页 > 博客文章 正文

Windows上原子操作(操作系统中的原子操作)

baijin 2024-09-26 06:58:25 博客文章 3 ℃ 0 评论

前言

原子操作和临界区/互斥体对比更轻量级,不过并不能代替临界区/互斥体,只能用于数值操作(加减/交换/赋值).原子操作是不可分割的.先看一下下面的代码.

//c语言代码
void add() {
    int i =1;
    i+=2; 
}

看一下生成汇编代码:

add:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 1    // int i =1;
        add      DWORD PTR [rbp-4], 2    // i+=2;
        nop
        pop     rbp
        ret

我们看到 i+=2 生成汇编指令,要先读取寄存器的值,然后和2进行加法运算.在多线程中就会出现一个线程读取寄存器的值,另外一个线程已经进行加法运算,这样造成最终值不是我们预期的值.

原子操作

#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>

#define THREADCOUNT 4						//线程数量

int num = 0;

DWORD WINAPI func(void *p)
{
	for (int i = 0; i < 10000; i++)
	{		
		InterlockedIncrement(&num);			//InterlockedIncrement让num++成为原子操作			
		//InterlockedExchangeAdd(&num, 1);              //效果和InterlockedIncrement一样
	}
	return 0;
}

int main(int argc, char *argv[])
{
	HANDLE hd[THREADCOUNT];
	for (int i = 0; i < THREADCOUNT; i++)
	{
		hd[i] = CreateThread(NULL, 0, func, NULL, 0, NULL);
	}
	WaitForMultipleObjects(THREADCOUNT, hd, TRUE, INFINITE);
	printf("num=%d\n", num);
	system("pause");
	return 0;
}

原子操作的速度要快于临界区和互斥体.

原子操作是如何实现的

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

int main(int argc, char* argv[])
{
	int i = 1;

	InterlockedIncrement(&i);  //反汇编,看一下

	return 0;
}

Windows上的原子操作,是使用CPU指令,所以锁定地址,该操作未完成之前,不让其他线程进行操作.

个人能力有限,如果您发现有什么不对,请私信我

如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表