目录
进程间通信机制
管道(无名管道、有名管道、信号)
system v ipc(共享内存、消息队列、信号灯集)
套接字--网络通信
1.管道
(1)无名管道
无名管道和有名管道取决于创建出的管道是否在文件系统中可见,无名管道只能用于具有亲缘关系的进程间通信,具有固定的读短和写端,是一种半双工的通信方式。
(2) 无名管道接口函数:
创建无名管道----pipe
#include <unistd.h>
int pipe(int pipefd[2]);
参数:
pipefd:存放读端和写端文件描述符的地址
pipefd[0] -- 读端
pipefd[1] -- 写端
返回值:
成功返回0,失败返回-1
例子:
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
int pfd[2] = {0};
int ret = pipe(pfd); //创建无名管道
pid_t pid = fork(); //创建进程
if(ret < 0)
{
perror("pipe");
exit(-1);
}
if(pid > 0)
{
char buf[10] = {0};
wait(NULL); //等待子进程结束
read(pfd[0],buf,5); // 接收管道数据
printf("%s\n",buf);
}
else
{
write(pfd[1],"hello",5);//向管道文件写入数据
exit(-1);
}
//printf("pfd[0] = %d pfd[1] = %d\n",pfd[0],pfd[1]);
return 0;
}
(3)无名管道读写特性
读特性:
写端存在:
有数据:成功读取的字节数
没有数据:阻塞、知道有数据为止
写端不存在:
有数据、返回成功读取的字节数
没有数据:返回0
写特性:
读端存在:
有空间:返回成功写入的字节数
无空间:阻塞,直到有空间为止
读端不存在:
无论有无空间----管道破裂
(4)有名管道
有名管道在创建后会在文件系统中以一个文件的方式存在,有名管道没有固定的读写端;
创建有名管道:-- mkfifo
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
参数:
pathname:有名管道名(可以包含路径)
mode:有名管道的初始权限
返回值:
成功返回0,失败返回-1
例子:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int ret = mkfifo("mtfifo",0664);
if(ret < 0)
perror("mkfifo");
pid_t pid = fork();
if(pid == 0)
{
int fd_w = open("mtfifo",O_WRONLY);
char buf[20] = {0};
while(1)
{
memset(buf,0,20);
fgets(buf,20,stdin);
write(fd_w,buf,strlen(buf));
}
}else
{
int fd_r = open("mtfifo",O_RDONLY);
char buf1[20] = {0};
while(1)
{
memset(buf1,0,20);
read(fd_r,buf1,20);
printf("%s",buf1);
}
}
return 0;
}
2.信号
信号是中断在软件层次上的一种模拟
kill -l :查看信号
信号的处理方式:
默认
忽略
捕获 -----signal
(1)liunx常见的信号如下所示:
(2) 信号相关的shell指令:
kill -信号编号 进程号
kill -9 1111 -----当前终端向进程id为1111的进程发送信号9
kill -9 -1111------当前终端向进程组id为1111的进程发送信号9
kill -9 -1 ---------表示当前终端除了init进程以外的其他进程发送信号9
(3)信号相关的接口函数:
信号量编号:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid,int sig);
参数:
pid:进程id
sig:信号量
返回值:成功返回0 失败返回-1
#include <signal.h>
int raise(int sig);
例子:
int main(int argc, char *argv[])
{
kill(18484,SIGKILL) //SIGKILL信号量或者填写对应信号量数字
return 0;
}
(4)定时器
一个进程中最多只能存在1个定时器
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
参数:
seconds:定时时间,单位为秒
返回值:
成功返回0 或者 上一个定时器定时的剩余时间
#include <unistd.h>
int pause(void);
功能:结合alarm函数使用,用于等待定时时间结束
例子:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int ret = alarm(5);
printf("ret = %d\n",ret);
pause();
return 0;
}
(5)捕获信号:------signal
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
参数:
signum:信号编号
handler:信号处理函数或者填SIG_IGN(忽略), SIG_DFL(默认)
例子:
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
void func(int num)
{
printf("hello!\n");
}
int main(int argc, char *argv[])
{
//signal(2,SIG_IGN);//忽略信号
signal(2,func);
while(1)
{
printf("aaaaaaaaaa\n");
sleep(1);
}
return 0;
}
3.ipc共享内存
共享内存因为有内存映射的操作,所以是所有进程间通信机制中效率最高的通信方式
共享内存的操作流程:
1.创建或者打开共享内存 ---chmget()
2.内存映射 ----- chmat()
3.读写共享内存
4.取消映射 chmdt()
5.删除共享内存 chmctl()
后续接下一章*******************************************