2015.3.3
星期二 阴天
IPC:进程间通信
pipe:无名管道:只能用于具有亲缘关系的进程之间
fifo: 有名管道:可以使互不相关的两个进程互相通信,有名管道可以通过路径名来指出,并且在文件系统中可见,通过文件io操作,不支持lseek()
管道创建:
无名:调用pipe();
有名管道:1.mkfifo(),2.open
信号的处理:有一个阶段:“革命的前夜”
实现进程间通信,用系统调用pipe()建立一个管道,两个子进程分别向管道中各写一句话,父进程从管道中读出来,并显示。
下面的代码有很多细节处理不好,仅供参考,基本功能能实现。
alarm();
pause();需要给信号设置一个处理函数,否则程序会被直接杀掉
信号处理的方法:
signal();部署一个信号处理函数
信号集函数;
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int pid1,pid2;
int main(int argc,char **argv)
{
int fd[2];
char outpipe[100], inpipe[100];
pipe(fd);
while((pid1 = fork()) == -1);
if(pid1 == 0)
{
sprintf(outpipe,"child 1 process is sending message!");
write(fd[1],outpipe,50);
sleep(2);
exit(0);
}
else
{
while((pid2 = fork()) == -1);
if(pid2 == 0)
{
sprintf(outpipe,"child 2 process is sending message!");
write(fd[1],outpipe,50);
sleep(2);
exit(0);
}
else
{
wait(NULL); //同步
read(fd[0],inpipe,50);
printf("%s
",inpipe);
sleep(1);
wait(NULL);
read(fd[0],inpipe,50);
printf("%s
",inpipe);
wait(NULL);
exit(0);
}
}
}
程序运行效果:
lg@lg-desktop:/mnt/hgfs/source test/file IO$ gcc pipe51.c
lg@lg-desktop:/mnt/hgfs/source test/file IO$ ./a.out
child 2 process is sending message!
child 1 process is sending message!
lg@lg-desktop:/mnt/hgfs/source test/file IO$
有名管道的创建,读,写操作:
创建:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define BUFFER_SIZE 1024
int main(int argc,char **argv)
{
int fd;
if(argc < 2)
{
fprintf(stdout,"Usage:%s<filename>
",argv[0]);
exit(-1);
}
if(mkfifo(argv[1],0644) < 0)
{
fprintf(stderr,"mkfifo() filed : %s
",strerror(errno));
exit(-1);
}
return 0;
}
写操作:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define BUFFER_SIZE 1024
int main(int argc,char **argv)
{
int fd;
if(argc < 2)
{
fprintf(stdout,"Usage:%s<filename>
",argv[0]);
exit(-1);
}
if((fd = open(argv[1],O_WRONLY)) < 0)
{
fprintf(stderr,"open fifo %s for writting faile:%s
",argv[1],strerror(errno));
exit(-1);
}
fprintf(stdout,"open fifo %s for writting successed.
",argv[0]);
char buffer[BUFFER_SIZE];
ssize_t n;
while(fgets(buffer,BUFFER_SIZE,stdin))
{
if((n = write(fd,buffer,strlen(buffer))) < 0)
{
fprintf(stderr,"write() failed on fifo : %s
",strerror(errno));
break;
}
}
return 0;
}
读操作:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#define BUFFER_SIZE 1024
int main(int argc,char **argv)
{
int fd;
if(argc < 2)
{
fprintf(stdout,"Usage:%s<filename>
",argv[0]);
exit(-1);
}
if((fd = open(argv[1],O_RDONLY)) < 0)
{
fprintf(stderr,"open fifo %s for reading faile:%s
",argv[1],strerror(errno));
exit(-1);
}
fprintf(stdout,"open fifo %s for reading successed.
",argv[0]);
char buffer[BUFFER_SIZE];
ssize_t n;
while(1)
{
if((n = read(fd,buffer,BUFFER_SIZE)) < 0)
{
fprintf(stderr,"read failed on %s:%s
",argv[1],strerror(errno));
exit(-1);
}
else if(n == 0)
{
fprintf(stderr,"peer closed fifo.
");
break;
}
else
{
buffer[n]=' ';
fprintf(stdout,"read %d bytes from :%s",n,buffer);
}
}
return 0;
}
注:三个程序分别实现相应的功能,执行时,创建三个可执行文件,分别先执行创建的程序,再执行读写程序,这里:读写端同时打开才读写操作才能实现,否则会阻塞
信号函数的使用:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
pid_t pid;
void driver_handler(int signo);
void saler_handler(int signo);
int main(int argc, char **argv)
{
if((pid = fork()) < 0)
{
perror("fork");
exit(-1);
}
if(pid > 0)
{
signal(SIGTSTP,driver_handler);
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGUSR1,driver_handler);
signal(SIGUSR2,driver_handler);
while(1)
{
pause();
}
}
else
{
signal(SIGINT,saler_handler);
signal(SIGQUIT,saler_handler);
signal(SIGTSTP,SIG_IGN);
signal(SIGUSR1,saler_handler);
signal(SIGUSR2,SIG_IGN);
while(1)
{
pause();
}
}
return 0;
}
void driver_handler(int signo)
{
if(signo == SIGUSR1)
{
printf("Let's gogogo!
");
}
if(signo == SIGUSR2)
{
printf("Stop the bus!
");
}
if(signo == SIGTSTP)
{
kill(pid,SIGUSR1);
}
}
void saler_handler(int signo)
{
pid_t ppid = getppid();
if(signo == SIGINT)
{
kill(ppid,SIGUSR1);
}
if(signo == SIGQUIT)
{
kill(ppid,SIGUSR2);
}
if(signo == SIGUSR1)
{
printf("please get off the bus
");
kill(ppid,SIGKILL);
exit(0);
}
}
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************