【发布时间】:2017-08-18 20:49:19
【问题描述】:
更少的编程问题,更多的是我正在寻求澄清的奇怪问题。考虑以下 C 程序:
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
volatile int counter = 0;
void incrementCounter()
{
counter += 1;
}
void* threadfunc()
{
for (int i = 0; i < 1000; i++)
{
incrementCounter();
}
}
int main()
{
pthread_t tids[100];
printf("Creating Threads...\n");
for (int i = 0; i < 100; i++)
{
pthread_create(&tids[i], NULL, threadfunc, NULL);
}
printf("Joining Threads...\n");
for (int i = 0; i < 100; i++)
{
pthread_join(tids[i], NULL);
}
printf("Finished. Counter = %d\n", counter);
}
这是我为大学作业写的。它应该显示在写入变量时多个线程不锁定的危险。
我在 Windows 10 上,所以我打开我安装的 Ubuntu Bash,然后运行
$ gcc -std=c99 -pthread main.c
$ ./a.out
打印出来
Creating Threads...
Joining threads...
Finished. Counter = 100000
好的……没错。它不应该是正确的。这应该被打破了!
我一次又一次地运行它,结果相同。 Counter = 100000 每一次!这可能是我一生中唯一一次让我对我的代码正常工作感到失望。
所以我登录了我的学校为 CS 学生共享的 Linux 系统。拉取我的代码,以同样的方式执行它,我得到:
Creating Threads...
Joining threads...
Finished. Counter = 99234
下一次,Counter = 99900,然后是Counter = 100000,然后是Counter = 99082
这就是我所期待的!
所以我的问题:
什么给了? Windows 的 Linux 子系统是什么导致我的代码不中断?
【问题讨论】:
-
您安装的
Ubuntu是否在具有单个 CPU 的虚拟机中运行? -
@Lou Linux Subsystem For Windows 不是虚拟机。
-
标准安装。在具有 4 个物理内核的 i7 上运行。
-
@n.m.:刚刚注意到,直到现在我才知道这个东西存在。据推测,至少根据 OP 的观察,它在后台进行了 some 线程虚拟化。向post a comment here 了解有关内部运作的详细信息也许是个好主意。
-
“我很失望我的代码能正常工作。” - 不可能,因为代码本身不正确。我建议您使用较小的线程池和更多 更大的计数目标。在
main的下一个线程启动之前,您启动的每个线程都已经完成其循环并终止,这是完全可行的。和/或/还使用全局互斥锁锁定每个线程的开头,该全局互斥锁最初锁定在main中,并且仅在所有线程启动时才释放,每个线程在开始循环之前获得它后立即释放它。
标签: c multithreading ubuntu pthreads windows-10