1.管道
2.共享内存
3.消息队列
4.信号量
5.网络套接字
pipe(无名管道),通常用于父子间沟通操作
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int pipefd[2];
if(pipe(pipefd)==-1){//pipe 在内核中打开了两个管道文件
perror("pipe");
return -1;
}
//pipefd[0] 读 pipefd[1] 写
pid_t id = fork();
if(id == -1){
perror("fork");
return -1;
}
//父子进程读写是不固定得,但是写数据得进程关闭读端,同理读数据关闭写端。
if(id == 0){ //子进程
close(pipefd[0]);//关闭读,只允许写
for(;;){
char str[128] = {};
fgets(str,128,stdin);
ssize_t ret = write(pipefd[1],str,strlen(str));
if(ret == -1){
break;
}
if(strcmp(str,"!quit\n")==0){
break;
}
}
close(pipefd[1]);
}else{
close(pipefd[1]);//关闭写 ,只允许读
for(;;){
char str[128] = {};
ssize_t ret = read(pipefd[0],str,128);
if(ret == -1){
break;
}
printf("recv:%s",str);
if(strcmp(str,"!quit\n")==0){
break;
}
}
close(pipefd[0]);
}
return 0;
}
有名管道,基于管道文件得通信。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define FIFO1 "/tmp/wfifo" //写
#define FIFO2 "/tmp/rfifo"//读
/*
FIFO1 服务端讲该文件作为写入,那么客户端只能从该文件中读取,不允许客户都向该文件写入
FIFO2 服务端讲该文件作为读取,那么客户端只能向该文件中写入
*/
int main(){
int ret = mkfifo(FIFO1,0664); //创建管道写
if(ret == -1){
perror("mkfifo");
return -1;
}
ret = mkfifo(FIFO2,0664); //创建管道读
if(ret == -1){
perror("mkfifo");
return -1;
}
int wfd = open(FIFO1,O_RDWR|O_NONBLOCK);
int rfd = open(FIFO2,O_RDWR|O_NONBLOCK);
if(wfd == -1||rfd == -1){
perror("open");
return -1;
}
pid_t id;
id = fork();
if(id == -1){
perror("fork");
close(wfd);
close(rfd);
}
if(id == 0){
for(;;){
char str[128] = {};
fgets(str,128,stdin);
if(write(wfd,str,strlen(str))<0){
break;
}
}
}else{
for(;;){
char str[128] = {};
if(read(rfd,str,128)<0){
if(errno == EAGAIN){
continue;
}
break;
}else
printf("recv: %s",str);
}
}
close(rfd);
close(wfd);
unlink(FIFO1);
unlink(FIFO2);
return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#define FIFO1 "/tmp/wfifo"
#define FIFO2 "/tmp/rfifo"
int main(){
int wfd = open(FIFO2,O_RDWR);
int rfd = open(FIFO1,O_RDWR);
if(wfd == -1||rfd == -1){
perror("open");
return -1;
}
pid_t id;
id = fork();
if(id == -1){
perror("fork");
close(wfd);
close(rfd);
}
if(id == 0){
for(;;){ //子进程发送数据给服务端
char str[128] = {};
fgets(str,128,stdin);
if(write(wfd,str,strlen(str))<=0){
break;
}
}
}else{
for(;;){ //父进程则一直读取服务端数据
char str[128] = {};
if(read(rfd,str,128)<=0){
break;
}
printf("recv: %s",str);
}
}
close(rfd);
close(wfd);
return 0;
}