Windows 临界区奇怪的行为

发布于 2024-10-12 17:33:04 字数 918 浏览 10 评论 0原文

我有两个共享的全局变量

int a = 0;
int b = 0;

和两个线程

// thread 1
for (int i = 0; i < 10; ++i) {
    EnterCriticalSection(&sect);
    a++;
    b++;
    std::cout << a " " << b << std::endl;
    LeaveCriticalSection(&sect);
}

// thread2
for (int i = 0; i < 10; ++i) {
    EnterCriticalSection(&sect);
    a--;
    b--;
    std::cout << a " " << b << std::endl;
    LeaveCriticalSection(&sect);
}

代码总是打印以下输出

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情空心 2024-10-19 17:33:04

每个线程都有一个特定的时间片,在该时间片内它会在被抢占之前执行。在您的示例中,时间片似乎比完成循环所需的时间长。

但是,您可以在将临界区留在循环内后调用 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.

黎歌 2024-10-19 17:33:04

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:

There is no guarantee about the order in which threads will obtain ownership of the critical section, however, the system will be fair to all threads.

白云悠悠 2024-10-19 17:33:04

对我来说,它看起来像是 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文