概述
Gcc 4.1.2版本之后,对X86或X86_64支持内置原子操作。就是说,不需要引入第三方库(如pthread)的锁保护,即可对1、2、4、8字节的数值或指针类型,进行原子加/减/与/或/异或等操作。有了这套内置原子操作函数,写程序方便很多。老宋根据Gcc手册中《Using the GNU Compiler Collection (GCC)》章节内容,将__sync_系列17个函数声明整理简化如下:
- type __sync_fetch_and_add (type *ptr, type value, ...)
// 将value加到*ptr上,结果更新到*ptr,并返回操作之前*ptr的值 - type __sync_fetch_and_sub (type *ptr, type value, ...)
// 从*ptr减去value,结果更新到*ptr,并返回操作之前*ptr的值 - type __sync_fetch_and_or (type *ptr, type value, ...)
// 将*ptr与value相或,结果更新到*ptr, 并返回操作之前*ptr的值 - type __sync_fetch_and_and (type *ptr, type value, ...)
// 将*ptr与value相与,结果更新到*ptr,并返回操作之前*ptr的值 - type __sync_fetch_and_xor (type *ptr, type value, ...)
// 将*ptr与value异或,结果更新到*ptr,并返回操作之前*ptr的值 - type __sync_fetch_and_nand (type *ptr, type value, ...)
// 将*ptr取反后,与value相与,结果更新到*ptr,并返回操作之前*ptr的值 - type __sync_add_and_fetch (type *ptr, type value, ...)
// 将value加到*ptr上,结果更新到*ptr,并返回操作之后新*ptr的值 - type __sync_sub_and_fetch (type *ptr, type value, ...)
// 从*ptr减去value,结果更新到*ptr,并返回操作之后新*ptr的值 - type __sync_or_and_fetch (type *ptr, type value, ...)
// 将*ptr与value相或, 结果更新到*ptr,并返回操作之后新*ptr的值 - type __sync_and_and_fetch (type *ptr, type value, ...)
// 将*ptr与value相与,结果更新到*ptr,并返回操作之后新*ptr的值 - type __sync_xor_and_fetch (type *ptr, type value, ...)
// 将*ptr与value异或,结果更新到*ptr,并返回操作之后新*ptr的值 - type __sync_nand_and_fetch (type *ptr, type value, ...)
// 将*ptr取反后,与value相与,结果更新到*ptr,并返回操作之后新*ptr的值 - bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
// 比较*ptr与oldval的值,如果两者相等,则将newval更新到*ptr并返回true - type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)
// 比较*ptr与oldval的值,如果两者相等,则将newval更新到*ptr并返回操作之前*ptr的值 - __sync_synchronize (...)
// 发出完整内存栅栏 - type __sync_lock_test_and_set (type *ptr, type value, ...)
// 将value写入*ptr,对*ptr加锁,并返回操作之前*ptr的值。即,try spinlock语义 - void __sync_lock_release (type *ptr, ...)
// 将0写入到*ptr,并对*ptr解锁。即,unlock spinlock语义
并编写了一个简单小例子,测试多个工作线程同时对同一个全局变量g_iSum进行加法操作时,使用__sync_fetch_and_add()原子操作进行原子加法,和不使用原子操作进行普通加法,观察它们运行结果的区别。每个工作线程加500万次,共10个工作线程,预期结果是5000万。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int g_iFlagAtom = 1;
#define WORK_SIZE 5000000
#define WORKER_COUNT 10
pthread_t g_tWorkerID[WORKER_COUNT];
int g_iSum = 0;
void * thr_worker(void *arg) {
printf ("WORKER THREAD %08X STARTUPn", (unsigned int)pthread_self());
int i=0;
for (i=0; i<WORK_SIZE; ++i) {
if (g_iFlagAtom) {
__sync_fetch_and_add(&g_iSum, 1);
} else {
g_iSum ++;
}
}
return NULL;
}
void * thr_management (void *arg) {
printf ("MANAGEMENT THREAD %08X STARTUPn", (unsigned int)pthread_self());
int i;
for (i=0;i<WORKER_COUNT;++i) {
pthread_join(g_tWorkerID[i], NULL);
}
printf ("ALL WORKER THREADS FINISHED.n");
return NULL;
}
int main(int argc, const char* argv[]) {
pthread_t tManagementID;
pthread_create (&tManagementID, NULL, thr_management, NULL);
int i=0;
for (i=0;i<WORKER_COUNT;++i) {
pthread_create(&g_tWorkerID[i], NULL, thr_worker, NULL);
}
printf ("CREATED %d WORKER THREADSn", i);
pthread_join(tManagementID, NULL);
printf ("THE SUM: %dn", g_iSum);
return 0;
}
最后
以上就是高高哈密瓜为你收集整理的Gcc内置原子操作__sync_系列函数简述及例程的全部内容,希望文章能够帮你解决Gcc内置原子操作__sync_系列函数简述及例程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复