- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有 2 个进程(一个“ls”进程和一个“grep”)。我正在使用管道在它们两者之间进行通信。但是 grep 进程无法从管道中读取。你能帮我弄清楚为什么会这样吗?
这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int pipe_fd[2];
int main()
{
pid_t p1,p2;
char *prog1_argv[4];
char *prog2_argv[2];
/* Build argument list */
prog1_argv[0] = "ls";
prog1_argv[1] = "-l";
prog1_argv[2] = "/";
prog1_argv[3] = NULL;
prog2_argv[0] = "grep";
prog2_argv[1] = "s";
prog2_argv[1] = NULL;
if (pipe(pipe_fd) < 0)
{
printf ("pipe failed");
}
p1 = fork();
if(p1 == 0)
{
printf("in child\n");
close(pipe_fd[0]);
if(dup2(pipe_fd[1],1)<0)
{
printf("dup failed:%d\n",errno);
}
close(pipe_fd[1]);
if(execvp (prog1_argv[0], prog1_argv)<0)
printf("exec failed");
}
if(p1>0)
{
printf("im in parent\n");
waitpid(p1,NULL,0);
printf("parent: child exited. Now test the pipe\n");
close(pipe_fd[1]);
if(dup2(pipe_fd[0],0)<0)
{
printf("dup failed:%d\n",errno);
}
close(pipe_fd[0]);
if(execvp (prog2_argv[0], prog2_argv)<0)
printf("exec failed");
}
}
最佳答案
从根本上说,您不应该等待 ls
在运行 grep
之前死去.
ls
命令可能会生成太多数据,以至于无法将其全部存储在管道中,因此 ls
命令将阻塞,直到另一个进程从管道读取,但另一个进程正在等待 ls
在它尝试从管道中读取任何内容之前完成。这是一个僵局。
此外,通过这样的等待,您强制执行串行执行,这会浪费多核的好处。
您应该进行一些小的改进。您报告错误的位置有很多。错误应该在标准错误流 ( stderr
) 上报告,而不是在 stdout
上报告.您还应该确保程序至少在其中一些错误后不会继续。
您不必测试任何 exec*()
的返回值系统调用。如果函数返回,则失败。同样,您应该确保进程在此之后退出。在这个程序中, child 是否继续并不重要;在许多程序中,不退出会导致困惑(例如,两个进程试图同时读取标准输入)。
不需要 pipe_fd
成为一个全局变量。请确保您的所有消息都以换行符结尾。你没有包括 <sys/wait.h>
所以你在没有原型(prototype)的情况下工作 waitpid()
功能——这通常是个坏主意。您应该将编译器设置为 fussy,以便它要求每个函数在使用或定义之前在范围内都有一个原型(prototype)。您可以在定义中初始化参数列表:
char *prog1_argv[] = { "ls", "-l", "/", NULL };
char *prog2_argv[] = { "grep", "s", NULL };
这具有不切换的关键有益副作用 prog_argv2[1]
使用 NULL 指针(如 Matthias 在他的 answer 中指出的那样。我还删除了数组的大小;第二个数组的尺寸为 2,需要为 3,但是当您像这样初始化时,编译器会执行数数。
您正确完成的一件重要的事情是确保管道文件描述符全部关闭。
这对我来说是正确的:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(void)
{
pid_t p1;
int pipe_fd[2];
char *prog1_argv[] = { "ls", "-l", "/", NULL };
char *prog2_argv[] = { "grep", "s", 0 };
if (pipe(pipe_fd) < 0)
{
fprintf(stderr, "pipe failed:%d\n", errno);
exit(1);
}
p1 = fork();
if (p1 == 0)
{
printf("In child\n");
close(pipe_fd[0]);
if (dup2(pipe_fd[1], 1) < 0)
{
fprintf(stderr, "dup failed:%d\n", errno);
exit(1);
}
close(pipe_fd[1]);
execvp(prog1_argv[0], prog1_argv);
fprintf(stderr, "exec failed:%d\n", errno);
exit(1);
}
if (p1 > 0)
{
printf("In parent\n");
close(pipe_fd[1]);
if (dup2(pipe_fd[0], 0) < 0)
{
fprintf(stderr, "dup failed:%d\n", errno);
exit(1);
}
close(pipe_fd[0]);
execvp(prog2_argv[0], prog2_argv);
fprintf(stderr, "exec failed:%d\n", errno);
exit(1);
}
fprintf(stderr, "Fork failed:%d\n", errno);
return(1);
}
关于c - 无法写入 2 个进程的管道 IPC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19095173/
我有这个代码 var myChart = new FusionCharts("../themes/clean/charts/hbullet.swf", "myChartId", "400", "75
既然写入是立即进行的(复制到内核缓冲区并返回),那么使用 io_submit 进行写入有什么好处? 事实上,它 (aio/io_submit) 看起来更糟,因为您必须在堆上分配写入缓冲区并且不能使用基
我正在使用 mootool 的 Request.JSON 从 Twitter 检索推文。收到它后,我将写入目标 div 的 .innerHTML 属性。当我在本地将其作为文件进行测试时,即 file:
最终,我想将 Vertica DB 中的数据抓取到 Spark 中,训练机器学习模型,进行预测,并将这些预测存储到另一个 Vertica DB 中。 当前的问题是确定流程最后部分的瓶颈:将 Spark
我使用 WEKA 库编写了一个 Java 程序, 训练分类算法 使用经过训练的算法对未标记的数据集运行预测 将结果写入 .csv 文件 问题在于它当前写出离散分类结果(即算法猜测一行属于哪个类别)。我
背景 - 我正在考虑使用 clickonce 通过 clickonce(通过网站)部署 WinForms 应用程序。相对简单的应用程序的要素是: - 它是一个可执行文件和一个数据库文件(sqlite)
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
我正在读取 JSON 文件,取出值并进行一些更改。 基本上我向数组添加了一些值。之后我想将其写回到文件中。当我将 JSONArray 写回文件时,会被写入字符串而不是 JSONArray 对象。怎样才
我为两个应用程序使用嵌入式数据库,其中一个是服务器,另一个是客户端。客户端应用程序。可以向服务器端发送获取数据请求以检索数据并显示在表格(或其他)中。问题是这样的:如何将获取的数据保存(写入)到页面文
是否有更好的解决方案来快速初始化 C 数组(在堆上创建)?就像我们使用大括号一样 double** matrix_multiply(const double **l_matrix, const dou
从问题得出问题:找到所有 result = new ArrayList(); for (int i = 2; i >(i%8) & 0x1) == 0) { result.add(i
由于某种原因,它没有写入 CSV。谁能明白为什么它不写吗? def main(): list_of_emails = read_email_csv() #read input file, cr
关闭。 这个问题是 not reproducible or was caused by typos 。它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能在这里出现,
我目前正在开发一个保存和加载程序,但我无法获得正确的结果。 编写程序: #include #include #define FILENAME "Save" #define COUNT 6 type
import java.io.*; public class Main2 { public static void main(String[] args) throws Exception {
我需要使用预定义位置字符串“Office”从所有日历中检索所有 iOS 事件,然后将结果写入 NSLog 和 UITextView。 到目前为止,这是我的代码: #import "ViewCo
我正在尝试将 BOOL 值写入 PFInstallation 中的列,但会不停地崩溃: - (IBAction)pushSwitch:(id)sender { NSUserDefaults *push
我以前在学校学过一些简单的数据库编程,但现在我正在尝试学习最佳实践,因为我正在编写更复杂的应用程序。写入 MySQL 数据库并不难,但我想知道让分布式应用程序写入 Amazon EC2 上的远程数据库
是否可以写回到ResourceBundle?目前我正在使用 ResourceBundle 来存储信息,在运行时使用以下内容读取信息 while(ResourceBundle.getBundle("bu
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我是一名优秀的程序员,十分优秀!