step4 . day7 进程间的通信方式

 进程间的通信方式:

无名管道(pipe)

有名管道 (fifo)

信号(signal)

system v5的进程间通信方式

共享内存(share memory)

消息队列(message queue)

信号灯集(semaphore set)

套接字(socket)

 

 

1.无名管道

只能用于具有亲缘关系的进程之间的通信

 

单工的通信模式,具有固定的读端和写端

 

无名管道创建时会返回两个文件描述符,分别用于读写管道

创建无名管道
#include <unistd.h>
int pipe(int pfd[2]);

返回值:成功时返回0,失败时返回EOF
参数:pfd 包含两个元素的整形数组,用来保存文件描述符
pfd[0]用于读管道;pfd[1]用于写管道


#include<stdio.h>
#include <unistd.h>
#include <string.h>
#define N 32

int main(int argc, const char *argv[])
{

pid_t pid;
int pfd[2];
char buf[N];
if(pipe(pfd)<0){
perror("pipe");
return -1;
}
pid = fork();
if(pid < 0){
perror("fork");
return -1;
}else if(pid == 0){
while(1){
strcpy(buf, "hello world from child process");
write(pfd[1],buf,strlen(buf));
sleep(1);
}
}
else{
while(1){
memset(buf,0,strlen(buf));
read(pfd[0],buf,N);
printf("recevie :%s\n",buf);
}
}
return 0;
}

2.有名管道

有名管道具有如下特点:
对应管道文件,可用于任意进程之间进行通信
打开管道时可指定读写方式
通过文件IO操作,内容存放在内存中

管道的创建
#include <unistd.h>
#include <fcntl.h>
int mkfifo(const char *path, mode_t mode);

返回值:成功时返回0,失败时返回EOF
参数: path 创建的管道文件路径
mode 管道文件的权限,如0666

使用: open()
read()
write()

进程1


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>

#define N 32
int main(int argc, const char *argv[])
{
int re;
unlink("myfifo");
re= mkfifo("myfifo",0666);

if(re<0){
perror("makfifo");
return -1;
}
char buf1[N];
char buf2[N];
strcpy(buf1,"hello world");
int fifofd;
fifofd = open("myfifo",O_RDWR);
while(1){
write(fifofd,buf1,N);
sleep(1);

memset(buf2,0,N);
re = read(fifofd,buf2,N);
if(re>0){
printf("%s\n",buf2);
}
}

return 0;
}

进程2


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>

#define N 32
int main(int argc, const char *argv[])
{
int re;

char buf1[N];
char buf2[N];
strcpy(buf2,"how are you");
int fifofd;
fifofd = open("myfifo",O_RDWR);
while(1){
memset(buf1,0,N);
re = read(fifofd,buf1,N);
if(re>0){
printf("%s\n",buf1);
}

write(fifofd,buf1,N);
sleep(1);
}

return 0;
}

3.信号通信

信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
linux内核通过信号通知用户进程,不同的信号类型代表不同的事件
Linux对早期的unix信号机制进行了扩展

进程对信号有不同的响应方式 
缺省方式
忽略信号
捕捉信号

终端命令 kill -l 可以查看信号

signal 函数定义

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

或者void (*signal(int signo, void (*handler)(int)))(int);

定义分解

void (* xxxx )(int);

xxxx = signal(int signo, aaa)

aaa = void (*handler)(int)

返回值:成功时返回原先的信号处理函数,失败时返回SIG_ERR
参数 :signo 要设置的信号类型
handler 指定的信号处理函数: SIG_DFL代表缺省方式; SIG_IGN 代表忽略信号;

signal函数不发信号,不阻塞,它使用回掉函数改变信号的行为。

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

void handle(int sig){
if(sig == SIGINT){
printf("I got a ctrl+C signal\n");
}else if(sig == SIGQUIT){
printf("I got a quit signal\n");
}else{
printf("other siganl\n");
}

}

int main(){

signal(SIGINT,handle);
signal(SIGQUIT,handle);
signal(SIGHUP,handle);
while(1){
sleep(1);
}

}

 

posted @ 2019-08-12 22:51  灰机12321  阅读(136)  评论(0编辑  收藏  举报