可以通过父进程的指针更改值吗?

Posted

技术标签:

【中文标题】可以通过父进程的指针更改值吗?【英文标题】:Can one changing value by pointer from the parent process? 【发布时间】:2021-05-20 22:33:10 【问题描述】:

我尝试更改子进程内用作while 循环参数的_Bool 标志。孩子需要退出while循环才能正常上车。

我想要一个其他结构中的指针来控制子进程的执行。这个想法的简单可重现示例可能会归结为(注意,这段代码会产生一个僵尸进程):

#include <stdio.h>
#include <unistd.h> 
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>

typedef struct 
  void (*loop)();
  _Bool done;
 __state;

__state state;

void state_loop() 
  pid_t pid;
  switch(pid = fork()) 
  case -1:
    perror("Failed to fork!\n");
    exit(1);
  case 0:
    printf("Connecting..\n");
    printf("Child's adress: %p\n", &state.done);
    while(!state.done) 
      ;;
    
    printf("Conected.\n");
  default:
    printf("Spawned a child..\n");
    signal(SIGCHLD, SIG_IGN);
  


__state state = state_loop, 0;

typedef struct 
  void (*set_state)(_Bool *flag_p);
  void (*flip)();
  // Data
  _Bool *flag_p;
 __controller;

__controller controller;

void controller_set_state(_Bool *flag_p) 
  controller.flag_p = flag_p;


void controller_flip() 
  *controller.flag_p = (_Bool)1 - *controller.flag_p;


__controller controller = 
  controller_set_state, controller_flip
;

int main(void) 
  printf("%i\n", state.done);
  controller.set_state(&state.done);
  state.loop();
  controller.flip();
  printf("%i\n", state.done);
  printf("%p:%p\n", &state.done, controller.flag_p);
  return 0;

上面的示例确实打印了父进程中的server.donecontroller.flag_p 的地址以及子进程中的server.done 地址。

怎么地址在所有地方都一样,但是子进程中的值被controller.flip更改后提示为0?

【问题讨论】:

是的,谢谢,现在听起来好多了。 如果您的loop 函数不接受任何参数,您应该通过void (*loop)(void) 明确说明。 您需要使用某种形式的进程间通信。你可以使用文件、套接字、共享内存、信号或类似的东西,但你必须使用一些东西。最简单的可能是在调用 fork 之前创建一个管道,然后在父级中将其关闭以发出信号。发送SIGUSR1 也可以。 【参考方案1】:

fork 创建一个独立的进程,它拥有自己的虚拟地址空间。除了少数例外(参见fork 的文档),子进程与其父进程完全相同。这意味着它会在同一虚拟地址获得自己的 state 单独副本。

如果您并不特别需要单独的进程,则可以转而分离一个线程。线程共享相同的内存空间,因此可以访问相同的state。但是,您需要通过pthread_mutex_t 之类的方式保护state 字段的读/写。

【讨论】:

以上是关于可以通过父进程的指针更改值吗?的主要内容,如果未能解决你的问题,请参考以下文章

(待续)进程控制---父子进程之间的复制

在子进程中重定向 STDOUT

子进程怎么操作父进程中的变量

什么是子进程和父进程

《Linux高性能服务器编程》学习总结(十三)——多进程编程

【linux c】子进程结束了,父进程还在,用ps -ef查看,子进程变成僵尸进程了。