- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我不确定为什么 waitpid() 会永久挂起。我假设 forks 应该在 execvp() 完成后终止并返回父进程。这没有发生。如果我注释掉 waitpid(),初始输出是正确的,但程序开始出现意外行为。
编辑
- execFirst() 处理列表中第一个命令的执行
- execMid() 处理列表中不是第一个或最后一个命令的任何命令的执行
- execLast() 处理列表中最后一个命令的执行
// Closes pipe
void closePipe(int *pPipe){
close(pPipe[0]);
close(pPipe[1]);
return;
}
// Opens the read end of pPipe and closes the write end
// @Private
void readFromPipe(int *pPipe){
dup2(pPipe[0],0);
close(pPipe[1]);
close(pPipe[0]);
return;
}
// Opens the write end of pPipe and closes the read end
// @Private
void writeToPipe(int *pPipe){
dup2(pPipe[1],1);
close(pPipe[0]);
close(pPipe[1]);
return;
}
// @Private
void execLast(sSettings *pSettings_, sCommand *pCommand, int iPipe[]){
readFromPipe(iPipe);
_execvp(pSettings_, pCommand);
}
// @Private
void execMid(sSettings *pSettings_, sCommand *pCommand, int iPipe1[], int iPipe2[]){
readFromPipe(iPipe1);
writeToPipe(iPipe2);
_execvp(pSettings_, pCommand);
}
// @Private
void execFirst(sSettings *pSettings_, sCommand *pCommand, int iPipe[]){
writeToPipe(iPipe);
_execvp(pSettings_, pCommand);
}
void execIndefDepthPipe(sSettings *pSettings_, sCommandList *pCommandList_){
int iPipe1[2];
int iPipe2[2];
int iStatus, iProcessId, iNumCommands = pCommandList_->iSize;
_pipe(pSettings_, iPipe1);
_pipe(pSettings_, iPipe2);
sCommand *pCommand;
do{
pCommand = popHeadNode(pCommandList_);
iProcessId = _fork(pSettings_);
if(iProcessId){ // If Parent
// continue; // Do nothing
waitpid(iProcessId, &iStatus, WUNTRACED); // It waits forever. I don't know why.
}
else { // Execute the commands as a child
if(pCommand != NULL) {
if(pCommandList_->iSize == (iNumCommands-1)) { // Exec First
//closePipe(iPipe2);
execFirst(pSettings_, pCommand, iPipe1);
}
else if(pCommandList_->iSize == 0) { // Exec Last
closePipe(iPipe1);
execLast(pSettings_, pCommand, iPipe2);
}
else { // Exec mid
execMid(pSettings_, pCommand, iPipe1, iPipe2);
}
}
_exit(0);
}
} while(pCommand != NULL);
return;
}
最佳答案
It is my assumption that the forks should terminate and return back to the parent process after the execvp() is done
如果你的意思和我想的一样,那你就错了。 exec
系列函数不会破坏子进程。他们将在子进程中执行的程序换成另一个,但进程保持不变。特别是,在 exec
调用的程序终止之前,该进程的 waitpid
不会返回。
如果您只是创建一个无需父进程的进一步帮助即可运行完成的子进程,这会很好。但是您正在尝试建立管道。您不能期望管道中的任何进程在它们全部完成之前终止。您尤其不能期望管道中的第一个进程在第二个进程创建之前终止。但这正是您的代码所做的:它在创建第二个进程之前等待第一个进程终止——与此同时,第一个进程已填满其管道并正在等待第二个进程读取它之前的一些数据可以继续。死锁。
您需要做的是在等待任何进程之前创建所有进程。您已经获得了所需的两个循环之一。不是在您调用的地方调用 waitpid
,而是将进程 ID 保存在数据结构中并转到下一次迭代。然后,在使用完整个“命令列表”后的第二个 循环中,在不指定任何特定进程 ID 的循环中调用 waitpid
等待;当每个进程终止时,从保存它们的数据结构中删除它的 ID;当该数据结构为空时,您就完成了。
此外,您需要检查每个系统调用 是否有错误,close
除外。 (这是 POSIX 中的一个错误,允许 close
失败;如果传递的文件描述符编号最初未打开,Unix 的明智实现只会返回错误,我还没有遇到一个需要关心那个的程序。如果你需要确保数据已经写入磁盘,你需要调用fsync
before close
; 但在管道上执行 fsync
是没有意义的。)
当我在这里时,对良好编程风格的一些观察:(1) 如果您停止使用匈牙利语前缀,您的代码将更易于阅读。 (1a) 标识符末尾无意义的下划线按照约定保留给宏内部定义的变量,C 没有宏卫生。 (1b) 以下划线开头的函数名由 C 标准保留,供 C 库内部使用;您围绕 fork
的包装器应命名为 forkWithSettings
- 描述性更强的东西会更好,但不知道这个设置对象中的所有内容我无法提出任何建议。 (2) 在宏伟的计划中放置花括号并不重要,但看在 Ghu 的份上,选择一种样式并在整个文件中始终如一地使用它。
关于c - C 中的无限管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30146801/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!