受这篇SO post的启发,我想知道以下代码片段是否会导致UB,因为
add_func()
和mul_func()
都可以同时以未指定的顺序修改counter
:
int counter = 0;
int mul_func(int x) {
counter *= x;
x = counter;
return x;
}
int add_func(int x) {
counter += x;
x = counter;
return x;
}
int main(void) {
int sum = add_func(3) + mul_func(2);
}
如果是这样,如果我向它们添加互斥体有帮助吗?:
int counter = 0;
pthread_mutex_d mtx;
int mul_func(int x) {
pthread_mutex_lock(&mtx);
counter *= x;
x = counter;
pthread_mutex_unlock(&mtx);
return x;
}
int add_func(int x) {
pthread_mutex_lock(&mtx);
counter += x;
x = counter;
pthread_mutex_unlock(&mtx);
return x;
}
int main(void) {
pthread_mutex_init(&mtx);
int sum = add_func(3) + mul_func(2);
pthread_mutex_destroy(&mtx);
}
虽然结果可能是不确定的(如许多多线程程序的情况),但即使没有数据竞争,“无序”性质是否仍然会导致 UB?
确实由编译器决定调用函数的顺序。它会在添加之前调用两者,但这就是你所知道的。
你的互斥锁不做任何事情;这些用于同步线程,而不是强制您的编译按照您想要的顺序评估事物。您的代码不会并行执行操作,它只是以未指定的顺序执行操作。
强制执行排序的正确方法是这样的
const int left=add_func(3);
const int right=mul_func(2);
int sum=left+right;
这样,编译器别无选择,只能按照您提供的顺序调用函数。