[源码]信号可靠信号不可靠信号相关

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:08   1913   0
/* 
 * File:   main.c
 * Author: luv letter
 *
 * Created on 2017年3月14日, 下午4:33
 */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>


/*
 3、信号可靠信号不可靠信号相关
编程程序,要去实现如下功能:
 父进程创建子进程1和子进程2、子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2;
 子进程2接受可靠信号的值,并发送给父进程,父进程把接受的值进行打印。
 提示:用sigqueue和sigaction实现
 */
void My_Sigaction(int signum, siginfo_t *st, void *dat)
{
 int ret = 0;
 // 这个是父进程的接收数据信号
 if (SIGRTMIN+1 == signum)
 {
  printf("parent rev signal\n");
  printf("parent rev pid2 signal data = %d\n", st->si_value.sival_int);
 }
 else if (SIGRTMIN == signum) //并将数据发送给父进程
 {
  printf("child recv signal\n");
  union sigval value;
  printf("My_Sigaction : st->si_value.sival_int = %d\n", st->si_value.sival_int);
  value.sival_int = st->si_value.sival_int;
  ret = sigqueue(getppid(), SIGRTMIN+1, value);
  if (-1 == ret)
  {
   perror("pid2: SIGRTMIN func err sigqueue: ");
   return ;
  }
 }
}


int main(int argc, char** argv)
{
 int ret = 0;
 struct sigaction act;
 sigemptyset(&act.sa_mask);
 act.sa_sigaction = My_Sigaction;
 ret = sigaction(SIGRTMIN+1, &act, NULL);
 if (-1 == ret)
 {
  perror("func err sigaction: ");
  return -1;
 }


 pid_t pid1, pid2;


 ///
 //         pid1
 ///
 
 pid1 = fork();
 if (-1 == pid1)
 {
  perror("func err fork() pid 1: ");
  return -1;
 }
 else if (0 == pid1) // 子进程 1
 {
  // 1 子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2;
  // SIGRTMIN+1
  // pid.txt
   // 读取 子进程2 的 pid
   // 用文件读取
  FILE *fp = NULL;
  while (1)
  {
   fp = fopen("pid.txt", "a+");
   if (NULL == fp)
   {
    continue;
   }
   else
   {
    break;
   }
  }
  printf("pid1: 打开文件成功\n");
  // 这里需要字符串转数字
  char revbuf[32] = {0};
  
  while (1)
  {
   char *tmp = fgets(revbuf, sizeof(revbuf), fp);
   if (NULL == tmp)
   {
    printf("pid1: 读取 pid2 中 ...\n");
    continue;
   }
   else 
   {
    printf("pid1: 读取 pid2 成功pid2 = %s\n", revbuf);
    break;
   }
  }
  if (NULL == fp)
  {
   fclose(fp);
   fp = NULL;
  }
  ret = system("rm -rf pid.txt");
  if (-1 == ret)
  {
   printf("pid1: func err system\n");
   return -1;
  }
  
  pid2 = atoi(revbuf);
  printf("pid1: 转化 pid2 为整数成功 = %d\n", (int )pid2 );
  union sigval value;
  value.sival_int = ((int)pid2) * 2;
  printf("pid1: value.sival_int  = %d\n", value.sival_int);
  ret = sigqueue((pid_t)pid2, SIGRTMIN, value);
  if (-1 == ret)
  {
   perror("pid1: func err sigqueue:");
   return -7;
  }
  printf("子进程退出...\n");
  exit(0);
 }
 ///
 //         pid2
 ///
 pid2 = fork();
 if (-1 == pid2)
 {
  perror("func err fork pid2:");
  return -2;
 }
 else if (0 == pid2) // 子进程 2 
 {
  // 3 接收子进程的信号, 并将数据发送给父进程
  struct sigaction act;
  ret = sigemptyset(&act.sa_mask);
  if (-1 == ret)
  {
   printf("pid2: func err sigemptyset\n");
   return -5;
  }
  act.sa_sigaction = My_Sigaction;
  ret = sigaction(SIGRTMIN, &act, NULL);
  if (-1 == ret)
  {
   perror("pid2: func err sigaction:");
   return -6;
  }
  
  // 1 保存自己的pid, 给子进程使用
  // 这个用文件保存
  FILE *fp = NULL;
  char pid_buf[18] = {0};
  
  fp = fopen("pid.txt", "w+");
  if (NULL == fp)
  {
   printf("pid2: open file failed\n");
   return -3;
  }
  printf("pid2: 打开文件成功...pid2 = %d\n", (int)getpid());
  int pid = (int )getpid();
  sprintf(pid_buf, "%d", pid);
  printf("pid2: pid2 = %s\n", pid_buf);
  ret = fputs(pid_buf, fp);
  if (EOF == ret)
  {
   printf("pid2: write error\n");
   return -4;
  }
  if (NULL != fp)
  {
   fclose(fp);
   fp = NULL;
  }
  printf("pid2: child 2 wait for 5 sec ...\n");
  int n = 5;
  while (n)
  {
   n = sleep(n);
   printf("pid2: child 2 wait end\n");
  }
  printf("pid2: 子进程 2 退出\n");
  exit(0);
 }
 printf("parent wait for 10 sec\n");
 int i = 10;
 while (i)
 {
  i = sleep(i);
  printf("parent wait for 10 sec end \n");
 }
 wait(pid1);
 wait(pid2);
 return (EXIT_SUCCESS);
}



另一套方法

/*
 pid_t pidArray[10];

 void My_Sigaction(int signum, siginfo_t *st, void *dat)
 {
  if (SIGRTMIN+1 == signum)
  {
   // 孩子1 收到了信号
   
   printf("孩子 1 收到信号, 他的值是 : %d\n", st->si_value.sival_int);
   pidArray[1] = st->si_value.sival_int;
  }
  else if (SIGRTMIN+2 == signum)
  {
   // 进程2 收到信号 
   
   printf("孩子 2 收到信号, 他的值是 : %d\n", st->si_value.sival_int);
   pidArray[3] = st->si_value.sival_int;
  }
  else if (SIGRTMIN+3 == signum)
  {
   // 父进程收到信号
   printf("父进程收到信号, 他的大儿子的pid = %d, 他的二儿子的pid = %d\n", pidArray[0], pidArray[1]);
   printf("二儿子发送的礼物是 = %d\n", st->si_value.sival_int);
  }
  else
  {
   printf("other signal recv\n");
  }
 }


int main(void)
{
 int ret = 0;
 
 // 信号发送区
 struct sigaction act;
 act.sa_flags = SA_SIGINFO;
 sigemptyset(&act.sa_mask);
 act.sa_sigaction = My_Sigaction;
 ret = sigaction(SIGRTMIN+1, &act, NULL);
 if (-1 == ret)
 {
  perror("func err sigaction: ");
  return -1;
 }
 
 ret = sigaction(SIGRTMIN+2, &act, NULL);
 if (-1 == ret)
 {
  perror("func err sigaction: ");
  return -2;
 }
 
 ret = sigaction(SIGRTMIN+3, &act, NULL);
 if (-1 == ret)
 {
  perror("func err sigaction: ");
  return -3;
 }
 
 int i = 0;
 pid_t pid = 0;
 for (i = 0; i < 2; i++)
 {
  pidArray[i] = pid = fork();
  if (-1 == pid)
  {
   perror("func err fork:");
   return -4;
  }
  else if (0 == pid)
  {
   break;
  }
 }
 
 // 父进程
 if (pid > 0)
 {
  printf("父进程启动\n");
  // 父进程向子进程 1 发送附加数据(子进程2 的 pid)
  union sigval value;
  value.sival_int = pidArray[1];
  ret = sigqueue(pidArray[0], SIGRTMIN+1, value);
 }
 // 子进程 1 
 if (0 == pid && 0 == i)
 {
  printf("子进程 1 启动\n");
  printf("子进程1 睡眠\n");
  sleep(5);
  printf("子进程1 睡眠醒来\n");
  union sigval value;
  pid_t pid;
  pid = getpid();
  value.sival_int = pid * 2;
  ret = sigqueue(pidArray[1], SIGRTMIN+2, value);
  exit(0);
 }
 // 子进程 2 
 if (0 == pid && 1 == i)
 {
  printf("子进程 2 启动\n");
  printf("子进程 2 睡眠\n");
  sleep(10);
  printf("子进程 2 睡眠醒来\n");
  // 子进程2 发送信号给父进程
  union sigval value;
  value.sival_int = pidArray[3];
  printf("子进程2 给父进程发送信号的数据 %d\n", pidArray[3]);
  ret = sigqueue(getppid(), SIGRTMIN+3, value);
  exit(0);
 }
 sleep(2);
 pid_t mypid = 0;
 while (1)
 {
  while ((mypid = waitpid(-1, NULL, WNOHANG)) > 0)
  {
   printf("pid = %d\n", mypid);
  }
 }
 
 return 0;
}
*/


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP