编译器内建,可以代替多线程全局变量自加、自减等操作,并且效率高于使用线程锁。
type为8字节以下的整形数
函数(加、减、与、或、非、异或)共12个:
type __sync_fetch_and_add (type *ptr, typevalue, ...)
type __sync_fetch_and_sub (type *ptr, typevalue, ...)
type__sync_fetch_and_or (type *ptr, typevalue, ...)
type __sync_fetch_and_and (type *ptr, typevalue, ...)
type __sync_fetch_and_xor (type *ptr, typevalue, ...)
type __sync_fetch_and_nand (type *ptr, typevalue, ...)
注意:GCC 4.4及更高版本__sync_fetch_and_nand:*ptr = ~(tmp &value);之前版本是:*ptr = ~tmp & value。
type __sync_add_and_fetch (type *ptr, typevalue, ...)
type __sync_sub_and_fetch (type *ptr, typevalue, ...)
type __sync_or_and_fetch (type *ptr, typevalue, ...)
type __sync_and_and_fetch (type *ptr, typevalue, ...)
type __sync_xor_and_fetch (type *ptr, typevalue, ...)
type __sync_nand_and_fetch (type *ptr, typevalue, ...)
注意:GCC 4.4及更高版本__sync_nand_and_fetch*ptr = ~(tmp & value);之前版本是:*ptr = ~tmp & value。
bool__sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)
如果ptr = ptr == oldval ? newval :oldval,成功返回1。
type__sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...)
同上,成功返回ptr替换之前的值。
__sync_synchronize(...)
发出一个full memory barrier内存屏障,作用是该屏障之前的指令不能移动到屏障下边执行,下边的指令也不可移动到上面执行。
type__sync_lock_test_and_set (type *ptr, type value, ...)
将ptr赋值为valuevoid__sync_lock_release (type *ptr, ...)
将ptr赋值为0
示例程序如下:
运行环境gcc (GCC) 4.4.4 20100726 (Red Hat 4.4.4-13)
- #include <stdio.h>
- #include <stdint.h>
- int main(int argc, char **argv) {
- uint64_t i = 8 ;
- setvbuf(stdout, NULL, _IONBF, 0) ;
- fprintf(stdout, "i = 8[%lu]\n", __sync_fetch_and_add(&i, 1)) ;
- fprintf(stdout, "i = 9[%lu]\n", __sync_fetch_and_sub(&i, 1)) ;
- fprintf(stdout, "i = 8[%lu]\n", __sync_fetch_and_or(&i, 1)) ;
- fprintf(stdout, "i = 9[%lu]\n", __sync_fetch_and_and(&i, 1)) ;
- fprintf(stdout, "i = 1[%lu]\n", __sync_fetch_and_xor(&i, 1)) ;
- fprintf(stdout, "i = 0[%lu]\n", __sync_fetch_and_nand(&i, 1)) ; /*i = ~(i&1) */
- fprintf(stdout, "i = 18446744073709551615[%lu]\n", i) ;
- i = 8 ;
- fprintf(stdout, "i = 9[%lu]\n", __sync_add_and_fetch(&i, 1)) ;
- fprintf(stdout, "i = 8[%lu]\n", __sync_sub_and_fetch(&i, 1)) ;
- fprintf(stdout, "i = 9[%lu]\n", __sync_or_and_fetch(&i, 1)) ;
- fprintf(stdout, "i = 1[%lu]\n", __sync_and_and_fetch(&i, 1)) ;
- fprintf(stdout, "i = 0[%lu]\n", __sync_xor_and_fetch(&i, 1)) ;
- fprintf(stdout, "i = -1[%ld]\n", __sync_nand_and_fetch(&i, 1)) ;
- fprintf(stdout, "i = 18446744073709551615[%lu]\n", i) ;
- i = 8 ;
- uint64_t j = 0 ;
- fprintf(stdout, "[%d]\n", __sync_bool_compare_and_swap(&i, 8, 2)) ;
- fprintf(stdout, "i = 2[%lu]\n", i) ;
- j = __sync_val_compare_and_swap (&i, 2, 8) ;
- fprintf(stdout, "i = 8[%lu]\n", i) ;
- fprintf(stdout, "j = 2[%lu]\n", j) ;
- __sync_synchronize() ;
- i = __sync_lock_test_and_set (&j, 10) ;
- fprintf(stdout, "i = 2[%lu]\n", i) ;
- fprintf(stdout, "j = 10[%lu]\n", j) ;
- __sync_lock_release (&i) ;
- __sync_lock_release (&j) ;
- fprintf(stdout, "i = 0[%lu]\n", i) ;
- fprintf(stdout, "j = 0[%lu]\n", j) ;
- return 0 ;
- }
详细信息详见GCC文档 6.51 6.52 6.53 6.54 6.55章节
网址: http://gcc.gnu.org/onlinedocs/gcc