Windows 临界区奇怪的行为
我有两个共享的全局变量
int a = 0;
int b = 0;
和两个线程
// thread 1
for (int i = 0; i < 10; ++i) {
EnterCriticalSection(§);
a++;
b++;
std::cout << a " " << b << std::endl;
LeaveCriticalSection(§);
}
// thread2
for (int i = 0; i < 10; ++i) {
EnterCriticalSection(§);
a--;
b--;
std::cout << a " " << b << std::endl;
LeaveCriticalSection(§);
}
代码总是打印以下输出
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
9 9
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
0 0
这很奇怪,看起来线程正在工作依次..有什么问题吗?
谢谢。
I have two shared global variables
int a = 0;
int b = 0;
and two threads
// thread 1
for (int i = 0; i < 10; ++i) {
EnterCriticalSection(§);
a++;
b++;
std::cout << a " " << b << std::endl;
LeaveCriticalSection(§);
}
// thread2
for (int i = 0; i < 10; ++i) {
EnterCriticalSection(§);
a--;
b--;
std::cout << a " " << b << std::endl;
LeaveCriticalSection(§);
}
The code always prints the following output
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
9 9
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
0 0
That is quite strange, looks like threads are working sequentally.. What's the problem with that?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
每个线程都有一个特定的时间片,在该时间片内它会在被抢占之前执行。在您的示例中,时间片似乎比完成循环所需的时间长。
但是,您可以在将临界区留在循环内后调用
Sleep(0)
来主动放弃控制。Each thread has a specific time slice during which it executes before being preempted. In your example, the time slice seems to be longer than the time required to complete the loop.
However, you can actively yield control by calling
Sleep(0)
after leaving the critical section inside the loop.IMO 关键部分离开/输入在您的示例中非常快,以至于另一个线程不够快无法在此时执行输入部分。
尝试进行一些(可能是随机的)睡眠来减慢代码速度,以查看所需的效果。
注意:
EnterCriticalSection 的默认超时约为 30 天左右(意味着无限),因此您不能期望该函数会超时。 文档说:
IMO critical section leave/enter in your example is so fast that another thread is not fast enough to execute enter section during this moment.
Try to put some (maybe random) sleeps to slow down code to see desired effects.
Note:
Default timeout for EnterCriticalSection is like 30 days or so (means infinty) so you cannot expect that function will time out. And documentation says:
对我来说,它看起来像是 http://social.msdn.microsoft.com/forums/en-US/windowssdk/thread/980e5018-3ade-4823-a6dc-5ddbcc3091d5/
请看2006年6月28日的例子
(不幸的是我找不到微软关于CriticalSection变化的原始文章)
你能在Windows XP上试试你的代码吗?它显示了什么?
我猜测 I/O 操作 (cout) 会像 Sleep() 调用一样影响调度,因此从 Windows Vista 开始,在 CS 内执行 I/O 时,线程可能会导致其他线程饥饿。
For me it looks like the topic discussed in http://social.msdn.microsoft.com/forums/en-US/windowssdk/thread/980e5018-3ade-4823-a6dc-5ddbcc3091d5/
Please look the example from June 28, 2006
(unfortunately I cannot find the original article by Microsoft telling about the change of CriticalSection)
Could you try your code on Windows XP? What does it show?
I guess that I/O operations (cout) affect the scheduling similarly to a Sleep() call, so starting with Windows Vista a thread could cause starvation of other threads when doing I/O inside a CS.