C 如何用叉子和管子制作工艺环?
目前我正在学习C,我想用叉子和管子做一个由n个孩子组成的环过程,其中n是一个数字,在参数中输入,每个孩子可以与下一个孩子在一个方向上进行交流 我尝试在每个孩子向下一个孩子发送其pid时执行此操作,但我没有得到我想要的,例如,如果我创建3个孩子:C 如何用叉子和管子制作工艺环?,c,pipe,fork,child-process,C,Pipe,Fork,Child Process,目前我正在学习C,我想用叉子和管子做一个由n个孩子组成的环过程,其中n是一个数字,在参数中输入,每个孩子可以与下一个孩子在一个方向上进行交流 我尝试在每个孩子向下一个孩子发送其pid时执行此操作,但我没有得到我想要的,例如,如果我创建3个孩子: PID:1,循环中的i:0,接收到的i:0 PID:2,循环中的i:1,接收到的i:0 PID:3,循环中的i:2,接收到的i:0 但我应该得到: PID:1,循环中的i:0,接收到的i:3 PID:2,循环中的i:1,接收到的i:1 PID:3,循环中
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, const char * argv[]) {
if(argc != 2) {
fprintf(stderr, "Usage : %s <integer> [> 2]\n", argv[0]);
exit(EXIT_FAILURE);
}
int number_process = atoi(argv[1]);
if(number_process < 2) {
fprintf(stderr, "Usage : %s <integer> [> 2]\n", argv[0]);
exit(EXIT_FAILURE);
}
printf("Création de %d processus pour une élection : \n", number_process);
int i = 0, j = 0, k = 0;
int * t = (int *) malloc((2 * number_process) * sizeof(int));
for(k = 0; k < number_process; k++) {
pipe(&t[2*i]);
}
for(i = 0; i < number_process; i++) {
if(fork() == 0) {
for(j = 0; j < number_process*2; j++) {
if(j != 2*i && j != ((2*i+3)%(number_process*2))) {
close(t[j]);
}
}
close(t[(2*i+1)%(number_process*2)]);
close(t[((2*i+2)%(number_process*2))]);
int pid = (int) getpid();
write(t[(2*i+3)%(number_process*2)], &pid, sizeof(int));
int in = 0;
read(t[i*2], &in, sizeof(int));
printf("%d : %d\n", in, getpid());
exit(EXIT_SUCCESS);
}
}
return (EXIT_SUCCESS);
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,const char*argv[]{
如果(argc!=2){
fprintf(stderr,“用法:%s[>2]\n”,argv[0]);
退出(退出失败);
}
int number_进程=atoi(argv[1]);
if(进程数<2){
fprintf(stderr,“用法:%s[>2]\n”,argv[0]);
退出(退出失败);
}
printf(“工艺选择:\n”,工艺编号);
int i=0,j=0,k=0;
int*t=(int*)malloc((2*number_进程)*sizeof(int));
对于(k=0;k
以下是我在程序中发现的问题:
read()
将返回否定结果。在这种情况下,您可能会从read()
获得EBADF
EBADF
错误的来源,并注意管道未正确初始化。这是由于管线管道(&t[2*i])
应该使用k
而不是i
。找到此错误的另一种方法是使用地址消毒剂或Valgrind,这两种方法都可以立即找到错误(无需更改代码)。在循环中对循环变量进行范围界定也会立即发现此问题,因此使用for(int i=0;…)
而不是int i;对于(i=;…)
close()
函数。然而,这个错误是无害的fork()
之前执行fflush(stdout)
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
void usage(const char *prog) {
fprintf(stderr, "Usage : %s <integer> [> 2]\n", prog);
exit(1);
}
int main(int argc, const char * argv[]) {
if(argc != 2) {
usage(argv[0]);
}
int number_process = atoi(argv[1]);
if(number_process < 2) {
usage(argv[0]);
}
printf("Création de %d processus pour une élection : \n", number_process);
// Flush stdout before fork.
fflush(stdout);
// Do not cast the result of malloc
// Use sizeof(*pipes) instead of sizeof(int)
// Prefer descriptive variable names
int *pipes = malloc((2 * number_process) * sizeof(*pipes));
if (!pipes) {
perror("malloc");
exit(1);
}
// Scope loop variables in the loop
for (int i = 0; i < number_process; i++) {
int r = pipe(&pipes[2*i]);
if (r == -1) {
perror("pipe");
exit(1);
}
}
for (int i = 0; i < number_process; i++) {
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
// Let's avoid copy/pasting 2*i and (2*i+3)%(number_process*2)
// everywhere, which is hard to read
int infd = pipes[2*i];
int outfd = pipes[(2*i+3)%(number_process*2)];
for (int j = 0; j < number_process*2; j++) {
if (pipes[j] != infd && pipes[j] != outfd) {
close(pipes[j]);
}
}
int self = getpid();
ssize_t amt;
amt = write(outfd, &self, sizeof(int));
if (amt == -1) {
perror("write");
exit(1);
}
int in;
ssize_t r = read(pipes[i*2], &in, sizeof(int));
if (r == -1) {
perror("read");
exit(1);
}
printf("%d : %d\n", in, (int)getpid());
exit(0);
}
}
// Close pipes and wait for children to finish
for (int i = 0; i < number_process * 2; i++) {
close(pipes[i]);
}
for (int i = 0; i < number_process; i++) {
wait(NULL);
}
// Return at end of main() is implicitly "return 0".
}
#包括
#包括
#包括
#包括
#包括
#包括
无效用法(常量字符*prog){
fprintf(标准,“用法:%s[>2]\n”,程序);
出口(1);
}
int main(int argc,const char*argv[]{
如果(argc!=2){
用法(argv[0]);
}
int number_进程=atoi(argv[1]);
if(进程数<2){
用法(argv[0]);
}
printf(“工艺选择:\n”,工艺编号);
//在叉子前冲洗标准液。
fflush(stdout);
//不要强制转换malloc的结果
//使用sizeof(*管道)而不是sizeof(int)
//更喜欢描述性变量名
int*pipes=malloc((2*工艺编号)*尺寸(*管道));
如果(!管道){
佩罗尔(“马洛克”);
出口(1);
}
//循环中的作用域循环变量
for(int i=0;i
你怎么知道代码是错的?我用printf测试了它,其中I,curre