0

我在多进程程序中有一个错误。该程序接收输入并立即产生输出,不涉及网络,也没有任何时间参考。是什么让这个错误的原因难以追查是它只是偶尔发生。

如果我不断地运行它,它会产生正确和不正确的输出,没有可辨别的顺序或模式。

什么会导致这种不确定的行为?有没有可以提供帮助的工具?有可能存在未初始化的变量。我如何找到那些?

编辑:问题已解决,感谢任何建议 Race Condition的人。我没有想到它主要是因为我确信我的设计可以防止这种情况发生。问题是我使用了“wait”而不是“waitpid”,因此有时,当某个进程幸运地在我期望的进程之前完成时,事情的正确顺序就会变得疯狂。

4

7 回答 7

5

你说这是一个“多进程”程序——你能更具体一点吗?这很可能是您如何处理多个进程的竞争条件。

如果您能告诉我们更多关于流程如何交互的信息,我们或许能够提出一些可能性。请注意,尽管 Artem 建议使用调试器本身就很好,但您需要注意,引入调试器很可能会完全改变这种情况——尤其是在涉及竞争条件时。就我个人而言,我非常喜欢记录日志,但即使这样也可以巧妙地改变时间。

于 2009-06-06T19:39:13.020 回答
3

调度员!

基本上,当您有多个进程时,它们可以按照他们想要的任何奇怪的顺序运行。如果这些进程共享一个它们正在读取和写入的资源(无论是文件、内存还是某种 IO 设备),那么操作将以各种奇怪的顺序交错。举个简单的例子,假设你有两个线程(它们是线程,所以它们共享内存)并且它们都试图增加一个全局变量 x。

y = x + 1;
x = y

现在运行这些进程,但以这种方式交错代码

假设 x = 1

P1:

y = x + 1

所以现在在 P1 中,对于本地和堆栈上的变量 y y = 2,. 然后调度器进来并启动P2

P2:

y = x + 1
x = y

x 仍然是 1 进入这个,所以 1 已添加到它现在x = 2

然后P1结束

P1:

x = y

x 仍然是 2!我们将 x 增加了两次,但只得到了一次。因为我们不知道将如何发生,所以它被称为非确定性行为。

好消息是,您偶然发现了系统编程中最困难的问题之一,也是许多函数式语言人员的主要战斗口号。

于 2009-06-06T19:42:36.867 回答
3

您很可能正在查看竞争条件,即不可预测的,因此难以重现和调试不正确同步的线程或进程之间的交互。

这种情况下的非确定性源于进程/线程和内存访问调度。这是不可预测的,因为它受到大量外部因素的影响,包括网络流量和用户输入,这些因素不断导致中断并导致程序每次运行时线程中的实际执行顺序不同。

于 2009-06-06T19:45:03.350 回答
2

从基础开始...确保所有变量都具有默认值,并且在使用之前将所有动态内存清零(即使用 calloc 而不是 malloc)。应该有一个编译器选项来标记这个(除非你使用一些晦涩的编译器)。

如果这是 c++(我知道它应该是一个“c”论坛),有时对象创建和初始化滞后于变量赋值,这可能会咬你一口。例如,如果您有一个由多个线程同时使用的范围(如在单例或全局变量中),这可能会导致问题:

if (!foo) Foo tmp = new Foo();

如果您有多个线程访问上述内容,则第一个线程会找到 foo = null 并开始对象创建和分配,然后产生。另一个线程进来并发现 foo != null 所以跳过该部分并开始使用 foo。

于 2009-06-06T23:01:02.083 回答
2

可能有很多事情,内存泄漏,关键部分访问,未关闭的资源,未关闭的连接等。只有一个工具可以帮助您 - 调试器,或者尝试检查您的算法并找到错误,或者如果您成功指出有问题的部分,你可以在这里粘贴一个片段,我们会尽力帮助你。

于 2009-06-06T19:34:45.167 回答
1

我们需要查看有关您的代码的细节才能给出更准确的答案,但简而言之,当您有一个在多个进程或多个线程之间进行协调的程序时,线程执行时间的变量可能会增加不确定性你的申请。本质上,操作系统所做的调度会导致进程和线程乱序执行。根据您的环境和代码,操作系统所做的调度可能会导致截然不同的结果。您可以在 google 上搜索有关使用多线程进行乱序执行的更多信息以获取更多信息;这是一个很大的话题。

于 2009-06-06T19:39:09.883 回答
0

“多进程”是指多线程吗?如果我们有两个线程来执行这个例程

i = 1;
while(true)
{
    printf(i++);
    if(i > 4) i = 1;
}

通常我们希望输出类似于

112233441122334411223344

但实际上我们会看到类似的东西

11232344112233441231423

这是因为每个线程将以不同的速率使用 CPU。(日程安排背后有很多复杂的东西,我太弱了,无法告诉你背后的技术内容。)可以说,从普通人的角度来看,日程安排是非常随机的。

这是其他评论中提到的竞争条件的一个例子。

于 2009-06-06T19:42:31.890 回答