首页 > 其他 > 详细

管道和信号的简单用法

时间:2015-03-04 00:53:22      阅读:312      评论:0      收藏:0      [点我收藏+]

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\n",inpipe);
sleep(1);
wait(NULL);
read(fd[0],inpipe,50);
printf("%s\n",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>\n",argv[0]);
exit(-1);
}

if(mkfifo(argv[1],0644) < 0)
{
fprintf(stderr,"mkfifo() filed : %s\n",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>\n",argv[0]);
exit(-1);
}

if((fd = open(argv[1],O_WRONLY)) < 0)
{
fprintf(stderr,"open fifo %s for writting faile:%s\n",argv[1],strerror(errno));
exit(-1);
}

fprintf(stdout,"open fifo %s for writting successed.\n",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\n",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>\n",argv[0]);
exit(-1);
}

if((fd = open(argv[1],O_RDONLY)) < 0)
{
fprintf(stderr,"open fifo %s for reading faile:%s\n",argv[1],strerror(errno));
exit(-1);
}

fprintf(stdout,"open fifo %s for reading successed.\n",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\n",argv[1],strerror(errno));
exit(-1);
}
else if(n == 0)
{
fprintf(stderr,"peer closed fifo.\n");
break;
}
else
{
buffer[n]=‘\0‘;
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!\n");
}

if(signo == SIGUSR2)
{
printf("Stop the bus!\n");
}

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\n");
kill(ppid,SIGKILL);
exit(0);
}
}

***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************
***************************************************************************************************************************************************************

管道和信号的简单用法

原文:http://www.cnblogs.com/cnlg/p/4312162.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!