进程间能否传递指针?

Linux系统里的sigqueue函数支持信号携带参数,函数原型如下:

#include <signal.h>

int sigqueue(pid_t pid, int sig, const union sigval value);

参数value是一个共用体,定义如下:

union sigval{

  int sival_int;

  void *sival_ptr;

};

我注意到这个共用体中有一个是指针,就想到,进程间能不能传递指针呢,用程序验证

// 示例利用信号传递数据,本程序发送数据
// 选项-d 后跟待传递的数据,选项-s 后跟待发送的信号,选项-p 后跟目的进程ID
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
 union sigval value;
 int  signum = SIGTERM; // 默认发送SIGTERM
 pid_t  pid;
 int  i;

 /*初始化*/
 value.sival_int = 0; 

 /*检查参数的个数*/
 if (argc != 3 && argc != 5 && argc != 7) {
  printf("./send_data_signo <-d data> <-s signum> [-p][data]\n");
  exit(1);
 }

 /*从命令行参数解析出信号编号、PID以及待传递的数据*/
 for (i=1; i<argc; i++) {
  if (!strcmp(argv[i], "-d")) {
   value.sival_ptr = argv[i+1];  //指针指向参数中的字符串
   continue;
  }
  if (!strcmp(argv[i], "-s")) {
   signum = atoi(argv[i+1]);
   continue;
  }
  if (!strcmp(argv[i], "-p")) {
   pid = atoi(argv[i+1]);
   continue;
  }
 }

 /*利用sigqueue给pid发送信号signum,并携带数据value*/
 if (sigqueue(pid, signum, value) < 0) {
  perror("sigqueue");
  exit(1);
 }

 return 0;
}

 

// 示例利用信号传递数据,本程序接收数据
#include <signal.h>
#include <stdio.h>

/*三参数的信号处理程序*/
void handler_sigint(int signo, siginfo_t *siginfo, void * pvoid)
{
 printf("recv SIGINT, the data value is:%s\n",(char *) siginfo->si_ptr);
}

int main()
{
 struct sigaction act;
 
 /*赋值act结构*/
 act.sa_sigaction = handler_sigint;
 act.sa_flags = SA_SIGINFO;  // 指定使用三参数的信号处理函数
 /*安装信号处理函数*/
 sigaction(SIGINT, &act, NULL);
 
 while(1)
  ;

 return 0;
}

经过编译后运行如下:

在第一个终端中:

#./recv_data_signo

在第二个终端:

#ps -a

查看进程号,然后

#./send_data_signo -s 2 -d hello -p 4832

第一个终端显示:

Segmentation fault

所谓的Segmentation Fault段错误)就是指访问的内存超出了系统所给这个程序的内存空间

可见,即使成功传递了指针,但是在另一进程里仍然不能引用。

我们试一试同一个进程的情况.

#include <signal.h>

#include <stdio.h>

#include <stdlib.h>


void handler_sigint(int signo, siginfo_t *siginfo, void * pvoid)

{

 printf("recv SIGINT, the data value is:%s\n", (char *)(siginfo->si_ptr));

}


int main(int argc, char ** argv)

{
 struct sigaction act;

 union sigval value;

 int  signum = SIGTERM; 

 pid_t  pid;

 int  i;


 act.sa_sigaction = handler_sigint;

 act.sa_flags = SA_SIGINFO;  

 sigaction(SIGINT, &act, NULL);

 value.sival_ptr = NULL; 

 

 if (argc != 3 && argc != 5 ) {

  printf("./send_data_signo <-d data> <-s signum> \n");

  exit(1);

 }

 

 for (i=1; i<argc; i++) {

  if (!strcmp(argv[i], "-d")) {

   value.sival_ptr = argv[i+1];

   continue;

  }

  if (!strcmp(argv[i], "-s")) {

   signum = atoi(argv[i+1]);

   continue;

  }

 }

 pid = getpid();

 if (sigqueue(pid, signum, value) < 0) {

  perror("sigqueue");

  exit(1);

 }

 

 return 0;

}

 

编译运行:

#./send_data_signo -s 2 -d hello

recv SIGINT, the data value is:hello

同一个进程里能正常传递指针

参考文献:《Linux c编程实战》童永清

原文地址:https://www.cnblogs.com/fangyu/p/1815179.html