- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我运行这段代码时,我的程序被终止,但我似乎不明白为什么。
int pipefd[2];
pipe(pipefd);
pid = fork();
if(pid == 0){ //child process, receives data from pipe for execution
close(0);
dup(pipefd[0]);
close(pipefd[1]);
execvp(pipeCom2[0], pipeCom2);
}
else if (pid > 1){ //parent process writes data to pipe for execution
close(1);
dup(pipefd[1]);
close(pipefd[0]);
execvp(pipeCom1[0], pipeCom1);
waitpid(pid, &status, WUNTRACED);
}
我一直在使用 cat project1.c | 进行测试grep include 命令。它正确执行并显示我的程序中的所有包含语句。
所以 pipelineCom1 包含 {"cat", "project1.c"}
并且 pipelineCom2 包含 {"grep", "include"}
在程序的前面,我使用此代码覆盖输出,并在程序结束时恢复正常。因此,当进程被终止时,输出会变得困惑。
newConfig.c_lflag &= ~(ICANON| ECHOE | ECHO);
tcsetattr(0, TCSANOW, &newConfig);
最佳答案
将评论转换为答案。
您没有关闭足够的管道文件描述符。如果将描述符复制到标准输入或输出,则应关闭两个管道描述符。
Which other pipe file descriptors should I be closing?
你有:
int pipefd[2];
pipe(pipefd);
pid = fork();
if (pid == 0) //child process, receives data from pipe for execution
{
close(0);
dup(pipefd[0]);
close(pipefd[1]);
execvp(pipeCom2[0], pipeCom2);
}
else if (pid > 1) //parent process writes data to pipe for execution
{
close(1);
dup(pipefd[1]);
close(pipefd[0]);
execvp(pipeCom1[0], pipeCom1);
waitpid(pid, &status, WUNTRACED);
}
调用 dup()
后,您需要关闭两组代码中的 pipefd[0]
和 pipefd[1]
。您也可以使用 dup2() 代替 dup() ;这通常更简单。
在这个带有试用管道的程序中,很有可能在不添加缺少的 close()
操作的情况下一切都会好起来。然而,一般来说,关闭不需要的管道描述符是至关重要的,因为打开的描述符意味着进程不会得到它期望的 EOF,或者在应该得到 SIGPIPE 信号或写入错误时不会得到,因为进程的错误管道末端仍然打开。
execvp()
此外,父进程包含一个 execvp()
调用;以下代码仅在 exec 失败时执行。当进程运行 execvp()
(或任何其他 exec*()
函数)时,仅当执行操作失败时,调用才会返回。
如果您需要重置终端,请在其中一个 exec 调用之前执行此操作,或者创建两个子级并让父级关闭其所有管道描述符并等待子级完成(死亡),然后再重置终端。考虑信号处理。在执行其他程序之前重置终端会更简单。
Earlier in the program I override output with this code and return to normal at the end of my program. So when the process is killed output is messed up.
newConfig.c_lflag &= ~(ICANON| ECHOE | ECHO);
tcsetattr(0, TCSANOW, &newConfig);
假设您有一个带有 tcgetattr()
输出的 oldConfig
,您应该这样做:
tcsetattr(0, TCSANOW, &oldConfig);
在父进程运行execvp()
之前。
你说:
pipeCom1 contains {"cat", "project1.c"}
and pipeCom2 contains {"grep", "include"}
pipeCom1
和 pipeCom2
都具有以空(指针)结尾的参数字符串列表,这对于正确操作至关重要。例如,您可以使用如下所示的硬连线参数列表:
char *pipeCom1[] = { "cat", "project1.c", 0 };
char *pipeCom2[] = { "grep", "include", 0 };
如果您愿意,可以用 NULL 代替 0。
execvp()
失败时报告错误并退出您需要考虑 execvp()
失败后会发生什么。正确的答案很少是“继续,就像没有出问题一样”(这就是您的代码所做的)。
您应该考虑向标准错误报告错误。通常,您应该以失败状态退出,使用 exit(EXIT_FAILURE);
或 _exit(EXIT_FAILURE);
或这些的一些相关项。
#include <stdio.h>
#include <termios.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
struct termios oldConfig;
struct termios newConfig;
tcgetattr(0, &oldConfig); // Error check omitted
newConfig = oldConfig;
newConfig.c_lflag &= ~(ICANON| ECHOE | ECHO);
tcsetattr(0, TCSANOW, &newConfig); // Error check omitted
/* Do stuff without echoing enabled */
/* Now do some execution */
char *pipeCom1[] = { "cat", "project1.c", 0 };
char *pipeCom2[] = { "grep", "include", 0 };
int pipefd[2]; // Error check omitted
pipe(pipefd);
pid_t pid = fork();
if (pid == 0) //child process
{
close(0);
dup(pipefd[0]);
close(pipefd[1]);
close(pipefd[0]);
execvp(pipeCom2[0], pipeCom2);
perror(pipeCom2[0]);
exit(EXIT_FAILURE);
}
else if (pid > 1) //parent process
{
close(1);
dup(pipefd[1]);
close(pipefd[0]);
close(pipefd[1]);
tcsetattr(0, TCSANOW, &oldConfig);
execvp(pipeCom1[0], pipeCom1);
perror(pipeCom1[0]);
exit(EXIT_FAILURE);
}
}
假设 project1.c
是上面源代码的副本,则命令的输出为:
#include <stdio.h>
#include <termios.h>
#include <stdlib.h>
#include <unistd.h>
char *pipeCom2[] = { "grep", "include", 0 };
进程结束后终端处于正确模式。
关于c - 使用 pipeline() 和 execvp() 杀死我的程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39715220/
例如,如果运行 1 正在等待批准并触发运行 2,则应拒绝运行 1。 最佳答案 “待批准”状态具体来自 Approval Gates功能。 虽然您不能在触发新运行时明确拒绝“待批准”步骤,但您可以通过在
在 Azure DevOps Pipelines 中,似乎有两种我无法区分的概念和处理“工件”的方法。 管道工件 https://learn.microsoft.com/en-us/azure/dev
不确定是否有办法做到这一点,但我想查看之前运行的 yaml 管道中的参数,以便查看管道运行时输入或选择的内容。那可能吗?我发现的唯一解决方法是根据每个参数添加标签。 最佳答案 您可以从 Build 查
我正在运行我所有的测试用例,其中一些用例有时会失败,管道检测到它并使步骤和构建失败。这会阻止要执行的下一步(压缩报告文件夹)。我想将该 zip 文件作为电子邮件附件发送。 这是我的 bitbucket
我正在数据工厂中定义管道,我纠正了一些错误。第一个事件是调用 usql 脚本进行一些聚合,我更改了脚本很多时间,但错误仍然是: [{"errorId":"E_CSC_USER_SYNTAXERROR"
我正在尝试使用运行命令VSTS扩展名对VSTS版本定义执行helm命令,但问题是它无法在我配置的自定义生成代理上找到kubeconfig文件。我认为这是因为定义的构建步骤在单独的过程中运行。当我运行
我无法弄清楚 sklearn.pipeline.Pipeline 是如何工作的。 doc 中有一些解释.例如它们是什么意思: Pipeline of transforms with a final e
我在 azure 管道中有两个管道(也称为“构建定义”),一个正在执行系统测试,一个正在执行性能测试。两者都使用相同的测试环境。我必须确保系统测试管道运行时不会触发性能管道,反之亦然。 到目前为止我已
我遵循了这个指令 https://confluence.atlassian.com/bitbucket/use-ssh-keys-in-bitbucket-pipelines-847452940.ht
当使用 YAML 完成另一个管道时尝试触发 Azure 管道。有documentation表明您可以添加管道资源: resources: # types: pipelines | builds |
我正在尝试根据我发布到的每个环境对我的 Web.config 进行文件转换。大多数情况下,一切看起来都很好,直到我在发布管道上部署到我的 UAT 阶段。 在我的构建管道中,这是我正在使用的 YAML
脚本化管道中是否有任何方法可以将某个阶段标记为不稳定,但仅将该阶段显示为不稳定,而不在输出中将每个阶段标记为不稳定? 我可以做这样的事情: node() { stage("Stage1") {
我有针对特定环境(dev、qa、uat)的特定配置文件和另一个根 web.config。部署的代码读取 web.config。所以我一直在尝试复制内容或重命名 Azure Pipelines 中的文件
我的 Jenkins 中有很多 Pipeline 项目。我想将它们转换为多分支管道。是否可以不删除管道并创建新的多分支管道?怎么办? 最佳答案 假设您的管道位于 Jenkinsfile 中,则无需进行
我们正在使用扩展功能以安全的方式在我们的管道中重用模板。为了更轻松地定义模板的参数,我想使用变量,但我觉得这是不可能的。 但由于我在官方文档中找不到答案,所以我在这一轮提问。 我的 yml 文件如下所
如何访问UID Jenkins 管道工作中的变量? 我收到了 null什么时候: pipeline { agent any environment { def user
我正在摆弄管道以尝试减少整体运行时间。我想做的一件事是执行 docker pull ...在开始时,以便以后,当我真正需要它时,它已经为我准备好了。我想将它作为后台工作解雇,并让它在该任务结束后继续存
From here我了解到 Bitbucket Pipeline 支持 ifs 语句。 如何在 if 语句中执行多行块? 这不计算: script: - if [ $BITBUCK
我在运行 Jenkins 服务器(在 docker 容器内)的谷歌云中运行虚拟机。我正在尝试为我的应用程序构建一个 Docker 镜像,并使用 Jenkins 管道将其推送到 Google Conta
在构建和部署 docker image.Getting Unexpected value 'Steps' 在第 27 行之前,我试图将视频文件从 GPM 复制到 app/dist/asset/imag
我是一名优秀的程序员,十分优秀!