问:从文件中逐行读取并使用管道发送到 child 进程
Q: Read line to line from file and send to child process with pipes
我想要做的是从 .txt 中读取每一行,并将每一行发送到 child 进程之一,每个进程都会打印自己的行。
是这样的:
Txt:Abc
定义
转
Child 进程 1 将读取 Abc,child 进程 2 将读取 def 等等。
// Includes
// the child just get the file descriptor to read (the pipe)
void child(int fd) {
char buf[100]; // buffer to store data read
int ret; // the number of bytes that are read
while((ret = read(fd, buf, sizeof(buf))) > 0) {
// write the 'ret' bytes to STDOUT (which as file descriptor 1)
write(1, buf, ret);
}
}
int main (void) {
pid_t pid;
char buf[100];
int N_CHILDREN = 2;
int p[N_CHILDREN][2];
int i,j, ret;
int fdi;
// create the pipes
for(i=0; i<N_CHILDREN; i++) {
if (pipe(p[i]) == -1) {
perror("pipe"); // ALWAYS check for errors
exit(1);
}
}
//open the file
fdi = open("123.txt",O_RDONLY);
if (fdi < 0) {
perror("open"); // ALWAYS check for errors
exit(1);
}
// just spawn the children
for(j=0; j < N_CHILDREN;j++) {
pid = fork();
if (pid < 0) {
perror("fork"); // ALWAYS check for errors
exit(1);
}
if (pid == 0) { // child
close(p[j][1]); // close the writing part
child(p[j][0]); // call child function with corresp. FD
exit(0); // leave : the child should do nothing else
}
}
// don't need that part
for(j=0; j<N_CHILDREN; j++) {
close(p[j][0]); // close the read-part of pipes
}
// need to read file content, see comment in child() function
while ((ret = read(fdi, buf, sizeof(buf))) > 0) {
// write the data to all children
for(j=0; j<N_CHILDREN; j++) {
write(p[j][1], buf , ret); // we write the size we get
}
}
// close everithing
for(j=0; j<N_CHILDREN; j++) {
close(p[j][1]); // needed, see text after
}
close(fdi); // close read file
return(0); // main returns a int, 0 is "ok"
}
这是我得到的代码,如您所见,它获取文件的全部内容并打印 child 次。
使用低级系统调用很难读取行,除非您一次读取一个字符。相反,您可以使用标准的 C I/O 函数,如 fgets
将一行读入缓冲区并通过管道将其发送到子进程。
至于如何将单独的行发送到单独的进程,跳过内部循环,而是将当前子进程索引保存在一个变量中,您在循环结束时增加该变量并使用模运算符 "reset"快溢出的时候归零
类似
int current_child = 0; // Start with the first child
while (fgets(buf, sizeof buf, fp) != NULL)
{
// Send to current_child
// Continue to next child process
// Reset to zero if going of the end of the child-list
current_child = (current_child + 1) % N_CHILDREN;
}
我想要做的是从 .txt 中读取每一行,并将每一行发送到 child 进程之一,每个进程都会打印自己的行。 是这样的: Txt:Abc 定义 转
Child 进程 1 将读取 Abc,child 进程 2 将读取 def 等等。
// Includes
// the child just get the file descriptor to read (the pipe)
void child(int fd) {
char buf[100]; // buffer to store data read
int ret; // the number of bytes that are read
while((ret = read(fd, buf, sizeof(buf))) > 0) {
// write the 'ret' bytes to STDOUT (which as file descriptor 1)
write(1, buf, ret);
}
}
int main (void) {
pid_t pid;
char buf[100];
int N_CHILDREN = 2;
int p[N_CHILDREN][2];
int i,j, ret;
int fdi;
// create the pipes
for(i=0; i<N_CHILDREN; i++) {
if (pipe(p[i]) == -1) {
perror("pipe"); // ALWAYS check for errors
exit(1);
}
}
//open the file
fdi = open("123.txt",O_RDONLY);
if (fdi < 0) {
perror("open"); // ALWAYS check for errors
exit(1);
}
// just spawn the children
for(j=0; j < N_CHILDREN;j++) {
pid = fork();
if (pid < 0) {
perror("fork"); // ALWAYS check for errors
exit(1);
}
if (pid == 0) { // child
close(p[j][1]); // close the writing part
child(p[j][0]); // call child function with corresp. FD
exit(0); // leave : the child should do nothing else
}
}
// don't need that part
for(j=0; j<N_CHILDREN; j++) {
close(p[j][0]); // close the read-part of pipes
}
// need to read file content, see comment in child() function
while ((ret = read(fdi, buf, sizeof(buf))) > 0) {
// write the data to all children
for(j=0; j<N_CHILDREN; j++) {
write(p[j][1], buf , ret); // we write the size we get
}
}
// close everithing
for(j=0; j<N_CHILDREN; j++) {
close(p[j][1]); // needed, see text after
}
close(fdi); // close read file
return(0); // main returns a int, 0 is "ok"
}
这是我得到的代码,如您所见,它获取文件的全部内容并打印 child 次。
使用低级系统调用很难读取行,除非您一次读取一个字符。相反,您可以使用标准的 C I/O 函数,如 fgets
将一行读入缓冲区并通过管道将其发送到子进程。
至于如何将单独的行发送到单独的进程,跳过内部循环,而是将当前子进程索引保存在一个变量中,您在循环结束时增加该变量并使用模运算符 "reset"快溢出的时候归零
类似
int current_child = 0; // Start with the first child
while (fgets(buf, sizeof buf, fp) != NULL)
{
// Send to current_child
// Continue to next child process
// Reset to zero if going of the end of the child-list
current_child = (current_child + 1) % N_CHILDREN;
}