如何将 pid 的值保存在数据结构中并稍后使用 fork() 访问它?

Posted

技术标签:

【中文标题】如何将 pid 的值保存在数据结构中并稍后使用 fork() 访问它?【英文标题】:How can I save the value of pid in a data structure and access it later with fork()? 【发布时间】:2021-12-17 05:39:57 【问题描述】:

我有一个程序,我在其中创建了几个不同的子进程来模拟 shell 脚本。如果进程应该在后台运行,我正在做的是创建一个子进程,然后将它的进程 ID 存储在数据库中,以便下次运行命令时,我可以使用 waitpid(pid,status,WNOHANG )。

我遇到的问题是存储子进程 ID 的值,然后尝试访问它们。

这是我创建新子进程并将它们插入到接受 void * 作为“节点”的 DLL 的代码:

typedef void*Data;

extern void execCommand(Command command, Pipeline pipeline, Jobs jobs,
                             int *jobbed, int *eof, int fg) 
  CommandRep r=command;
  if (fg && builtin(r,eof,jobs))
    return;

  int pid=fork();
  if (pid==-1)
    ERROR("fork() failed");
  if (pid==0)
    // do some work as the child
   else if(fg && pid > 0) 
    // if you're a parent and this is a foreground process
    // wait for the most recent process that started running
    // then try to wait for existing children if they exist
    int c_stat = -999;
    waitpid(pid,&c_stat,0);
    attemptWait();
   else if (fg==0 && pid > 0) 
    // if you're a parent and this is a background process
    // add this childs process id to the list, and then
    // attempt to wait for all processes to finish
    dll_put(running_processes,(Data)&pid);
    attemptWait();
  

void attemptWait() 
  int j=-999;
  for(int i=0;i<dll_len(running_processes);i++) 
    j=waitpid(*(int *)dll_ith(running_processes, i),&j,WNOHANG);
    printf("child pid: %d\n",*(int *)dll_ith(running_processes, i));
    if((j)==(*(int *)dll_ith(running_processes, i))) 
      printf("[%d]+ Done", i);
     else if (j == -1) 
      printf("there was an error closing the %d-th process\n", i);
    
  

现在,发生的事情是,当我存储新创建的子进程的 pid 时,我将 pid 的地址传递给它以存储在数据结构中,但是下次调用 execCommand 时,pid 会更新,所以所有我在 DLL 中的 pid 被覆盖了,我每次输入命令时都试图关闭同一个进程。

如何获取存储在 DLL 中的整数值,这样我就可以使用它而不用担心它会被覆盖?

【问题讨论】:

请查看***.com/help/minimal-reproducible-example。 【参考方案1】:

我不知道您正在使用的dll_..() 函数,但很明显,当execFunction() 返回时,您总是存储超出范围的局部变量的地址。因此,您应该尝试分配一个缓冲区来存储该 pid:

pid_t *pid_ptr = malloc( sizeof *pid_ptr );
*pid_ptr = pid;
dll_put(running_processes, pid_ptr);

当您不再需要该 pid 时,不要忘记致电 free()(应该在孩子终止后)

【讨论】:

甜蜜!如果 pid_ptr 与我开始存储 pid 的范围相同,是否会被覆盖,因为我正在为 malloc 分配空间? 如果它总是 sa 地址(例如静态或全局变量),它也会被覆盖。不同之处在于,在您的情况下 any 访问存储的指针会导致 UB

以上是关于如何将 pid 的值保存在数据结构中并稍后使用 fork() 访问它?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NAudio 将声音文件加载到内存中并稍后使用?

如何将 np.arrays 附加到文件中并稍后将它们用于绘图目的

将文件插入 SQL 数据库并检索它

如何使用 Ruby 将数据保存到 JSON 中并在以后使用?

将 NSData 数组保存到 CoreData

如何将文件保存在路径中并使用 ../../ 从不同的路径 PHP 访问它