【问题标题】:Calling an executable file with execlp()使用 execlp() 调用可执行文件
【发布时间】:2015-05-11 17:12:30
【问题描述】:

我正在尝试编译 2 个可执行文件。其中一个是采样器,另一个是收集器。采样器必须从收集器的子代​​中调用。采样器一将一些数据写入共享内存,收集器应从共享内存中读取数据。我正在使用 execlp 调用 Sampler,但我认为我做错了什么。它没有用下面的代码写任何东西。但是当我手动执行采样器时,它会将数据写入共享内存,然后当我执行收集器时,它可以正确读取数据。 不久 execlp 函数不会正确调用采样器。为什么?

pid = fork();
if (pid == 0) {
  execlp("/home/gizux/Belgeler/ogr1grp14pro2/Sampler1","/home/gizux/Belgeler/ogr1grp14pro2/Sampler1", ShmID, NULL);
  exit(0);
}
else
{
//collector codes come here

}

如果我不使用 execlp() 并将 Sampler 的代码放在那里,它就可以工作。

pid = fork();
if (pid == 0) {
  ShmID = shmget(55667, 4*sizeof(int), IPC_CREAT | 0666);
  if (ShmID < 0) {
    printf("*** shmget error (server) ***\n");
    exit(1);
  }

  ShmPTR = (int *) shmat(ShmID, NULL, 0);
  if ((int) ShmPTR == -1) {
    printf("*** shmat error (server) ***\n");
    exit(1);
  }

  int random;

  random = rand()%100+1;

  ShmPTR[0] = r;
  ShmPTR[1] = random;

  r++;
  random = 0;
  printf("Sampler has filled %d %d in shared memory...\n",
        ShmPTR[0], ShmPTR[1]);

  exit(0);
}
else
{
//collector codes come here

}

【问题讨论】:

    标签: c shared-memory execl


    【解决方案1】:

    您应该在您的execlp 调用之后添加一些错误报告。 (记住:exec 成功后永远不会返回,所以如果你在 exec 之后到达语句,它就会失败。)

    execlp(...);
    perror("execlp failed");
    

    您可能会发现EFAULT 失败了。这是因为您将ShmID(一个整数)作为参数传递。 execlp 只处理字符串。您需要将整数转换为字符串(例如使用sprintf)并将其传递给execlp。然后它会出现在另一个程序的argv 中,它当然是一个字符串,所以你必须将它转换回一个数字。

    【讨论】:

    • 另外,我怀疑共享内存 ID 的范围是否扩展到 exec()。当然,SysV 共享内存 attachmentsexec() 中无法生存。单独的进程通常通过将相同的 key 传递给shmget() 来映射相同的段。
    • @Wumpus Q. Wumbley,我收到“错误地址”执行错误。
    • @JohnBollinger 您可以获取带有ipcs 的密钥 ID 列表,然后使用密钥 ID 删除带有@987654333 的密钥@所以我认为ID必须在进程之间保持一致。至少只要对象还活着。当你在删除第一个后用相同的密钥创建另一个时,你可能会得到一个新的 ID。
    • @JohnBollinger 所以你的意思是我应该将 shared memory key 传递给 sampler 而不是 shmid
    • @gizux strerror(EFAULT)"Bad address" 所以就像我说的那样。现在继续应用我的答案的第二部分......
    【解决方案2】:

    您的execlp() 呼叫错误。

      execlp("/home/gizux/Belgeler/ogr1grp14pro2/Sampler1","/home/gizux/Belgeler/ogr1grp14pro2/Sampler1", ShmID, NULL);
    

    the man page:

    int execlp(const char *file, const char *arg, ...);

    ShmID 不是const char *

    【讨论】:

    • 谢谢。我们正在与 gizux(问题的所有者)一起工作。我们修复了它,但它仍然无法正常工作。请寻找其他答案的cmets。谢谢。
    • 您还可以在strace 下运行您的进程(假设是Linux)并捕获您的进程进行的每个系统调用的输出。像这样:strace -f -o /path/to/output/file command args 其中commandargs 是您运行流程的方式。完成后,输出文件将包含所有系统调用,包括参数和返回值。查找所有 shmget()shmat() 调用并确保它们是正确的 - 使用相同的密钥,返回相同的 ID。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    相关资源
    最近更新 更多