http://en.cppreference.com/w/cpp/atomic/memory_order和其他C++ 11在线参考,将memory_order_acquire和memory_order_release定义为:
这似乎允许在获取操作之前执行获取后写入,这看起来很奇怪(通常的获取/释放操作语义限制所有内存操作的移动).
相同的在线资源(http://en.cppreference.com/w/cpp/atomic/atomic_flag)表明可以使用C++原子和上面提到的宽松内存排序规则构建自旋锁互斥:
lock mutex: while (lock.test_and_set(std::memory_order_acquire))
unlock mutex: lock.clear(std::memory_order_release);
Run Code Online (Sandbox Code Playgroud)
有了这个锁定/解锁的定义,如果确实以这种方式定义了memory_order_acquire/release,那么下面的简单代码就不会被破坏(即,不禁止对获取后写入进行重新排序):
Thread1:
(0) lock
(1) x = 1;
(2) if (x != 1) PANIC
(3) unlock
Thread2:
(4) lock
(5) x = 0;
(6) unlock
Run Code Online (Sandbox Code Playgroud)
以下执行是否可行:(0)锁定,(1)x = 1,(5)x = 0,(2)PANIC?我错过了什么?
我试图使用LD_PRELOAD机制插入对pthread_cond_broadcast的调用.我插入的pthread_cond_broadcast函数只调用原始的pthread_cond_broadcast.但是,对于一个非常简单的pthread代码,其中pthread_cond_wait和pthread_cond_broadcast都被调用,我最终在glibc(对于glibc 2.11.1)或程序挂起(对于glibc 2.15)中有一个段错误.关于这方面的任何线索都在发生?
插入代码(编译为共享库):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <dlfcn.h>
static int (*orig_pthread_cond_broadcast)(pthread_cond_t *cond) = NULL;
__attribute__((constructor))
static void start() {
orig_pthread_cond_broadcast =
(int (*)()) dlsym(RTLD_NEXT, "pthread_cond_broadcast");
if (orig_pthread_cond_broadcast == NULL) {
printf("pthread_cond_broadcast not found!!!\n");
exit(1);
}
}
__attribute__((__visibility__("default")))
int pthread_cond_broadcast(pthread_cond_t *cond) {
return orig_pthread_cond_broadcast(cond);
}
Run Code Online (Sandbox Code Playgroud)
简单的pthread程序:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t cond_mutex;
pthread_cond_t cond_var;
int condition;
void *thread0_work(void *arg) {
pthread_mutex_lock(&cond_mutex);
printf("Signal\n");
condition = 1;
pthread_cond_broadcast(&cond_var);
pthread_mutex_unlock(&cond_mutex);
return NULL;
}
void *thread1_work(void *arg) …Run Code Online (Sandbox Code Playgroud)