gpt4 book ai didi

c - 如何在 C 中通过命令行参数传递管道和其他值?

转载 作者:太空狗 更新时间:2023-10-29 15:42:21 26 4
gpt4 key购买 nike

我正在尝试创建多个程序,其中第一个启动所有必需的 IPC 元素。我遇到的问题是使用第一个值执行辅助程序。我尝试了以下方法:

int sem_id = semget (key1, 4, IPC_CREAT | 0666);
int shmid = shmget(key2, 1024, 0644 | IPC_CREAT);
int pipe1[2];
if (pipe (pipe1)){
printf("Error: %s",strerror(errno));
exit(1);
}

if(execl("/home/tropix/program-3","/home/tropix/program-3", sem_id, shmid, pipe1, (char*)0) == 0){
fprintf(stderr, "File Execution of program 3 failed.\n");
exit(1);
}

程序 3 没有执行,所以我的 execl 语句显然有问题。如果我删除变量 sem_id、shmid 和 pipe2,它就会运行。

感谢您的任何建议。

编辑:添加了用于创建 shmid 和 sem_id 的语句。我可以将这些 int 打印到标准输出,所以我确定它们具有值(value)。至于程序 3 是否正在执行,请参阅程序 3:

main(int argc, char *argv[]){
int x;
printf("Number of args = %d", argc);
for(x=0;x<argc;x++){
printf("arg#: %d, %s\n",x,argv[x]);
}
}

另一个注意事项:我已经编译了程序 3。如果我删除 execl 参数并将它们替换为带引号的词(“test”),它们将在子页面中显示为参数。但在这种情况下,程序 3 中没有打印任何内容。

最佳答案

程序的参数必须都是字符串。

因此,要将信号量 ID、共享内存 ID 和文件描述符传递给执行程序,需要调用程序代码将数字转换为字符串,然后执行程序将字符串转换回数字,然后使用适本地。

您的代码没有显示“pipe2”...我假设它是一个简单的 int , 但如果它是一个数组(如 pipe1 是),那么你需要用 0 或 1 下标它来获取相关的文件描述符:

char shmarg[20];
char semarg[20];
char piparg[20];
int semid = semget (key1, 4, IPC_CREAT | 0666);
int shmid = shmget(key2, 1024, 0644 | IPC_CREAT);
int pipe1[2];
const char *cmd = "/home/tropix/program-3";

if (pipe(pipe1))
{
printf("Failed to create pipe: %s\n", strerror(errno));
exit(1);
}

snprintf(shmarg, sizeof(shmarg), "%d", shmid);
snprintf(semarg, sizeof(semarg), "%d", semid);
snprintf(piparg, sizeof(piparg), "%d", pipe2);

execl(cmd, cmd, semarg, shmarg, piparg, (char*)0);
fprintf(stderr, "File Execution of program 3 failed.\n");
exit(1);

不清楚你为什么有pipe1创建;你需要用它做适当的管道。如果execl()返回,它失败了。您不需要测试它的返回值。


来自评论:

[I'm] just cutting out the relevant sections for simplicity [...] [I'm] not sure what you mean about the "appropriate plumbing" with pipe1? Can you tell me how it should be done, or refer me to some information on how I can initialize the pipe and pass it to the next file? I realize creating the pipe in the program that requires it might be a better option, but in this case, initializing it in program 1 is a requirement.

问题的简单性是个好主意...

我假设在调用 pipe() 之间和 execl() , 有一个 fork()那被省略了。否则,pipe()没有任何意义。

据推测,创建管道的目的是让子进程与父进程对话,或者让父进程与子进程对话。有双向管道,但它们既不是标准的也不是可移植的;因此,我假设您有一个常规的单向管道。由于您将文件描述符编号作为参数传递给子项,因此我们不会为子项重定向标准输入或标准输出 - 这是您经常(但不总是)对管道执行的操作。

因此,您修改后的代码可以是(删除空行以避免滚动条):

char shmarg[20];
char semarg[20];
char piparg[20];
int semid = semget(key1, 4, IPC_CREAT | 0666);
int shmid = shmget(key2, 1024, 0644 | IPC_CREAT);
int pipe1[2];
const char *cmd = "/home/tropix/program-3";
if (pipe(pipe1))
{
printf("Failed to create pipe: %s\n", strerror(errno));
exit(1);
}
pid_t pid = fork();
if (pid < 0)
err_exit("Failed to fork");
else if (pid > 0)
{
/* Do parental things */
close(pipe1[0]);
...write to pipe1[1]...
}
else
{
/* Do childish things */
/* Assuming child is reading from pipe */
close(pipe1[1]);
snprintf(shmarg, sizeof(shmarg), "%d", shmid);
snprintf(semarg, sizeof(semarg), "%d", semid);
snprintf(piparg, sizeof(piparg), "%d", pipe1[0]);
execl(cmd, cmd, semarg, shmarg, piparg, (char*)0);
fprintf(stderr, "File Execution of program 3 failed.\n");
exit(1);
}

显然,如果管道由父级读取并由子级写入,您需要兼顾关闭和指定的文件描述符编号。

几乎总是,您最终至少关闭了从 pipe() 返回的两个文件描述符之一。 .如果将管道重定向到标准输入或标准输出,通常使用 dup2()复制管道的适当末端,然后关闭从 pipe() 返回的两个文件描述符.由于所有这些都与管道有关,因此俗称管道。

关于c - 如何在 C 中通过命令行参数传递管道和其他值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5928600/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com