跳过导航链接 | |
退出打印视图 | |
Oracle Solaris Studio 12.3:C 用户指南 Oracle Solaris Studio 12.3 Information Library (简体中文) |
编译器提供头文件 mbarrier.h,此头文件中针对 SPARC 和 x86 处理器定义了多种内存边界内部函数。这些内部函数可在开发者使用自己的同步基元编写多线程代码时使用。请参阅处理器文档,以确定特殊情况下需要使用这些内部函数的时间以及是否需要使用这些内部函数。
mbarrier.h 头文件支持的内存排序内部函数包括:
__machine_r_barrier()-这是读取边界。它确保边界前的所有装入操作能够在边界后的所有装入操作之前完成。
__machine_w_barrier()-这是写入边界。它确保边界前的所有存储操作能够在边界后的所有存储操作之前完成。
__machine_rw_barrier()-这是读写边界。它确保边界前的所有装入和存储操作能够在边界后的所有装入和存储操作之前完成。
__machine_acq_barrier()-这是具有 acquire 语义的边界。它确保边界前的所有装入操作能够在边界后的所有装入和存储操作之前完成。
__machine_rel_barrier()-这是具有 release 语义的边界。它确保边界前的所有装入和存储操作能够在边界后的所有存储操作之前完成。
__compiler_barrier()-阻止编译器跨边界移动内存访问。
除 __compiler_barrier() 内部函数之外的所有边界内部函数都将生成内存排序指令。在 x86 平台上,这些指令为 mfence、sfence 或 lfence 指令。在 SPARC 平台上,这些指令为 membar 指令。
__compiler_barrier() 内部函数不会生成指令,但会通知编译器所有以前的内存操作必须在启动任何后续内存操作之前完成。实际结果是:所有的非本地变量和带有 static 存储类说明符的本地变量将会在边界前返回存储在内存中,然后在边界后重新下载,并且在此过程中编译器不会将边界前的操作与边界后的操作弄混。编译器不会将边界之前的内存操作与边界之后的内存操作混合。所有其他的边界均隐含 __compiler_barrier() 内部函数的行为。
在以下示例中,__compiler_barrier() 内部函数的存在将阻止编译器合并两个循环:
#include "mbarrier.h" int thread_start[16]; void start_work() { /* Start all threads */ for (int i=0; i<8; i++) { thread_start[i]=1; } __compiler_barrier(); /* Wait for all threads to complete */ for (int i=0; i<8; i++) { while (thread_start[i]==1){} } }