// 修改自 http://www.gpfeng.com/?p=451 // 环境:glibc 2.33,gcc 11.1.0,gcc test.c -O0 -S #include #include #include #include #define MAX_THREADS 10 char sum = 0; char sum1 = 0; pthread_barrier_t barr; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; __attribute__ ((noinline)) void *thread_add_func0(void * param) { pthread_barrier_wait(&barr); int i; for (i = 0; i < *((int*)param); i++) { pthread_mutex_lock(&lock); pthread_mutex_unlock(&lock); } } __attribute__ ((noinline)) void *thread_add_func1(void * param) { pthread_barrier_wait(&barr); int i; for (i = 0; i < *((int*)param); i++) { pthread_mutex_lock(&lock); sum++; pthread_mutex_unlock(&lock); } } __attribute__ ((noinline)) void *thread_add_func2(void * param) { pthread_barrier_wait(&barr); int i; int j = 0; for (i = 0; i < *((int*)param); i++) { pthread_mutex_lock(&lock); if (j == 0) { sum += 3; j = 1; } else { sum -= 1; j = 0; } pthread_mutex_unlock(&lock); } } __attribute__ ((noinline)) void *thread_add_func3(void * param) { pthread_barrier_wait(&barr); int i; for (i = 0; i < *((int*)param); i++) __sync_add_and_fetch(&sum, 1); } void test_func(void* (*func)(void *), int threads, int loop, const char *name) { pthread_barrier_init(&barr, NULL, threads + 1); pthread_t tids[MAX_THREADS]; int i; sum = 0; for (i = 0; i < threads; i++) pthread_create(&tids[i], NULL, func, (void*)&loop); pthread_barrier_wait(&barr); time_t start = time(NULL); for (i = 0; i < threads; i++) pthread_join(tids[i], NULL); printf("%s:\tsum: %d, time: %d seconds\n", name, sum, time(NULL) - start); } int main(int argc, char *argv[]) { int loop = 8; int threads = 4; printf("threads: %d, loops per thread: %d\n", threads, loop); test_func(thread_add_func0, threads, loop, "mutex-void"); // 结果为 0,不正确 test_func(thread_add_func1, threads, loop, "mutex-sum"); test_func(thread_add_func2, threads, loop, "mutex-sum-2"); test_func(thread_add_func3, threads, loop, "gcc atomic add"); printf("\n"); return 0; }