进程间通信-信号

来源:互联网 发布:360浏览器mac版百度云 编辑:程序博客网 时间:2024/03/29 18:26

关于信号在进程间的通信,这是一个比较复杂的东西,本人不在这里做过多的介绍.....如果想系统的学习,请参考《unix环境高级编程这本书》

 

我在这里只展示几个例子:

用守护进程实现文件的同步...由子进程1改一个文件,守护进程2,检查到文件已经改变,并通过信号告诉给父进程,父进程实现输出....程序有点复杂,但思路还是比较清晰的

守护进程的创建:

在daemonize.h文件中

#include<syslog.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<fcntl.h>
#include<sys/resource.h>

void daemonize(const char *cmd)
{
int i,fd0,fd1,fd2;
pid_t pid;
struct rlimit r1;
struct sigaction sa;
umask(0);

if(getrlimit(RLIMIT_NOFILE,&r1) < 0)
{
   perror("can't get file limit");
   exit(0);
}
if((pid = fork())<0)
{
   perror("%s:can't fork");
   exit(0);
}
else if(pid != 0)
   exit(0);
setsid();

sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if(sigaction(SIGHUP,&sa,NULL) < 0)
{
   printf("can't ignore SIGHUP/n");
   exit(0);
}
if((pid = fork())<0)
{
   perror("%s:can't fork");
   exit(0);
}
else if(pid != 0)
   exit(0);
if(chdir("/") < 0)
{
   perror("can't chang directory to /");
   exit(0);
}

if(r1.rlim_max == RLIM_INFINITY)
   r1.rlim_max = 1024;
for(i = 0;i < r1.rlim_max;i++)
   close(i);

fd0 = open("/dev/null",O_RDWR);
fd1 = dup(0);
fd2 = dup(0);

openlog(cmd,LOG_CONS,LOG_DAEMON);
if(fd0 != 0 || fd1 != 1 || fd2 != 2)
{
   syslog(LOG_ERR,"unexpected file descriptors %d %d %d",fd0,fd1,fd2);
   exit(0);
}
}

 

主程序的实现,信号通性

#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<setjmp.h>
#include"daemonize.h"
#define MAXLINE 4096
void fun()
{
char buff[MAXLINE]="";
static int i=0;
sprintf(buff,"the file is appent %d number/n",i);
write(1,buff,MAXLINE);
i++;
};
int main(int argc,char *argv[])
{
long fp;
int i,j;
long pos;
pid_t pid1,pid2;
char buf[MAXLINE] ="";
if( (fp = open("a.txt",O_RDWR)) == -1)
{
   perror("open file error/n");
   return 0;
}

pos = lseek(fp,0,SEEK_END);
if((pid1=fork()) < 0)
{
   perror("fork error:");
   return 0;
}
else if(pid1 == 0)
{
   /* in child1 */
   while(1)
   {
    int n;
    i++;
    sleep(2);
    sprintf(buf,"zhang%d/n",i);
    n = strlen(buf);
    write(fp,buf,n);
    fsync(fp);
   }
   close(fp);
   exit(0);
}
else
{
   long pos1;
   pos1 = pos;
   pid_t pid = getpid();
   if((pid2 = fork())< 0)
   {
    perror("fork error:");
    return 0;
   }
   else if (pid2 == 0)
   {
    /*in child2 */
    long fl;
    daemonize("");
    while(1)
    {
     if((fl = open("/root/c_code/class/linux_program/3/a.txt",O_RDWR)) == -1)
     {
      syslog(LOG_ERR,"open file error");
      return 0;
     }
    
     pos = lseek(fl,0,SEEK_END);
     close(fl);
     if(pos != pos1)
     {
      syslog(LOG_ERR,"unexpected pos pos1 %d %d",pos,pos1);
      kill(pid,SIGUSR1);
     }
     pos1 = pos;
    }
    exit(0);
   }
   else
   { /* in parent */
    signal(SIGUSR1,fun);
    while(1)
    {
     pause();
    }
     
   }
}
return 0;

}

原创粉丝点击