双线程递增为何数值异常
#include <stdio.h> #include <stdlib.h> #include "common.h" #include "common_threads.h" volatile int counter = 0; int loops; void *worker(void *arg) { int i; for (i = 0; i < loops; i++) { counter++; } return NULL; } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "usage: threads <loops>\n"); exit(1); } loops = atoi(argv[1]); pthread_t p1, p2; printf("Initial value : %d\n", counter); Pthread_create(&p1, NULL, worker, NULL); Pthread_create(&p2, NULL, worker, NULL); Pthread_join(p1, NULL); Pthread_join(p2, NULL); printf("Final value : %d\n", counter); return 0; }
为了阐述这个现象,我将 变量称为counter
每个线程都试图递增counter变量。由于counter++操作不是原子的(即它分解为读取counter的值、增加1、然后写回counter)
当两个线程几乎同时执行这一操作时,会出现以下情况:
线程1读取counter的值(假设为100)。
线程2也在此时读取了相同的counter值(100)。
线程1将值增加到101并写回counter。
线程2也将它读取的值(100)增加到101并写回counter,覆盖了线程1的结果。
这样,本来应该增加两次(每次增加1)的counter只增加了1次。这就是为什么当loops值很高时
最终的counter值会小于预期(2 * loops)的原因。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。