如何在C中的父进程和子进程之间传递变量

  • 本文关键字:子进程 之间 变量 进程 c
  • 更新时间 :
  • 英文 :


我的问题是,如何在进程之间传递X值,我不想为此使用全局变量。

int main(int argc, char *argv[])
{
pid_t pid;
int x;
x = 1;
pid=fork();
// Daqui para baixo executa o fork
if (pid == 0){ //Processo filho
printf("Processo Filhon");
x = x + 2;
printf("Somando 2 ao X, temos: %dn", x);
exit(0);
}

else
{ //Processo pai
printf("Processo pain");
printf("O valor inicial de X é: %dn", x);
wait(NULL);
x = x * 4;
printf("Agora multiplicando o valor de X por 4 temos: %dn", x);
printf("Criança completan");
}
return 0;
}

我只是想用shmget打印X值,但我得到了-1,我现在只是在测试我是否可以用传递X值

int main(int argc, char *argv[])
{
pid_t pid;
int x;
int shmid;
int *shmptr;
x = 1;
shmid = shmget(x, 4*sizeof(int), IPC_CREAT | 0666);
shmptr = (int *) shmat(shmid, NULL, 0);
pid=fork();
// Daqui para baixo executa o fork
if (pid == 0){ //Processo filho
printf("Processo Filhon");
printf("%dn",shmid);
x = x + 2;
printf("Somando 2 ao X, temos: %dn", x);
exit(0);
}

else
{ //Processo pai
printf("Processo pain");
printf("O valor inicial de X é: %dn", x);
wait(NULL);
x = x * 4;
printf("Agora multiplicando o valor de X por 4 temos: %dn", x);
printf("Criança completan");
}
return 0;
}

分叉时,您正在创建一个与当前流程完全相同的流程。它还复制数据,这样您就可以访问与主进程上完全相同的东西,除了pid(对fork((调用的返回(。

所以你的x值被复制了。如果您在子进程中更改它,即使您使用全局变量,它也不会在父进程中更改

int x = 0;
pid = fork();
if (pid == 0) // Child process
{
printf("%dn", x); // will print 0
x++;
}
else
{
printf("%dn", x); // Will print 0
}
printf("%dn", x); // Will print 0 in the parent process and 1 in the child process

如果您想从子进程中检索X值,您应该查看waitpid函数。

下面是一个如何使用它的例子:

int pid = fork();
if (pid == -1)
exit(1);
if (pid == 0) // Child
{
exit(42);
}
int wstatus;
if (waitpid(pid, &wstatus, 0) == -1)
exit(1);
if (!WIFEXITED(wstatus))
exit(1);
printf("process exit status: %dn", WEXITSTATUS(wstatus)); // 42

在POSIX系统上,还可以使用实时信号在进程之间发送多达64位的数据。根据POSIX 72.4.2实时信号生成和交付

本节介绍了支持实时信号生成和传递的功能。

一些信号生成函数,如高分辨率定时器到期、异步I/O完成、进程间消息到达和sigqueue()函数,支持指定应用程序定义的值,无论是明确作为函数的参数还是在sigevent结构参数中。sigevent结构在<signal.h>中定义,并且至少包含以下成员:

Member Type            Member Name             Description
int                    sigev_notify            Notification type.
int                    sigev_signo             Signal number.
union sigval           sigev_value             Signal value.
void(*)(union sigval)  sigev_notify_function   Notification function.
(pthread_attr_t*)      sigev_notify_attributes Notification attributes.

sigval并集在<signal.h>中定义,并且至少包含以下成员:

Member Type            Member Name             Description
int                    sival_int               Integer signal value.
void*                  sival_ptr               Pointer signal value.

当应用程序定义的值为int类型时,应使用sival_int成员;当应用程序定义的值是指针时,应使用CCD_ 7成员。

发送值很简单:

int value = ...;
union sigval sv;
memset( &sv, 0, sizeof( sv ) );
sv.sival_int = value;
int rc = sigqueue( pid, SIGRTMAX, sv );

在具有64位指针的系统上,您可以破解使用sival_ptr指针字段发送64位数据的方法:

uint64_t value = ...;
union sigval sv;
memset( &sv, 0, sizeof( sv ) );
sv.sival_ptr = ( void * )( uintptr_t ) value;
int rc = sigqueue( pid, SIGRTMAX, sv );

您可以使用信号处理程序来检索值:

void handler( int sig, siginfo_t *info, void *context )
{
int value = info->si_value.sival_int;
...
}
...
struct sigaction sa;
memset( &sa, 0, sizeof( sa ) );
sa.sa_sigaction = handler;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction( SIGCHLD, &sa, NULL );

或者,使用sigwaitinfo():

sigset_t sigSet;
memset( &sigSet, 0, sizeof( sigSet ) );
sigemptyset( &sigSet );
sigaddset( &sigSet, SIGRTMAX );
sigprocmask( SIG_BLOCK, &sigSet, NULL );
siginfo_t siginfo;
int sigNum = sigwaitinfo( &sigSet, &siginfo );
if ( SIGRTMAX == sigNum )
{
int value = siginfo.si_value.sival_int;
...
}

最新更新