您的位置:首页 > 编程语言

原子操作

2013-11-03 16:34 465 查看

定义

webopedia:
Atomic implies indivisibility and irreducibility, so an atomic operation must be performed entirely or not performed at all.

An operation during which a processor can simultaneously read a location and write it
 in the same bus operation. This prevents any other processor or I/O device from writing or reading
memory until the operation is complete.


osdev:
An atomic operation is an operation that will always be executed without any other process being able to read or change state that
is read or changed during the operation. It is effectively executed as a single step, and is an important quality in a number of algorithms that deal with multiple indepent processes, both in synchronization and algorithms that update shared data without
requiring synchronization.


所谓的原子操作,取的就是“原子是最小的、不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源。也就是他确保了在同一时刻只有唯一的线程对这个资源进行访问。这有点类似互斥对象对共享资源的访问的保护,但是原子操作更加接近底层,因而效率更高。

原子操作(atomic operation)是不需要synchronized,不会被线程调度机制打断,这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。

特性

1. 在单处理器下,一个操作只包括一个cpu指令可以保证是原子操作。如果一个操作包含多个cpu指令不是原子操作。

2. 在多处理器下,由于一个cpu指令周期可能包含多个总线周期,就有可能出现其他处理器在一个指令执行期间访问了其相关的状态。因此,多处理器下,指令执行期间还必须锁总线,才能保证CPU指令的原子性

原子性不可能由软件单独保证--必须需要硬件的支持,因此是和架构相关的。在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。

应用

尽量使用系统自带的,或者是提供的原子操作函数。这些函数,对不同CPU类型,做了较好的封装,更加易用。
windows Synchronization Functions

Linux Built-in Functions for Atomic Memory Access

C++ 11 Atomic Operations Library

示例程序:

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

#define THREAD_COUNT 20

static int count = 0;

void* test_func(void *arg)
{
int i = 0;
for(i=0; i < 20000; ++i){
__sync_fetch_and_add(&count, 1);
}

return NULL;
}

int main(int argc, const char* argv[])
{
pthread_t id[THREAD_COUNT];
int i = 0;

for(i=0; i < THREAD_COUNT; ++i){
pthread_create(&id[i], NULL, test_func, NULL);
}

for(i=0; i < THREAD_COUNT; ++i){
pthread_join(id[i], NULL);
}

printf("count = %d\n", count);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  并发编程 线程 芯片