管道算法和进程间通信
管道的实现
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define BUFSIZE 1024
int main()
{
int pd[2],len = 0;
__pid_t pid;
char buf[BUFSIZE];
if(pipe(pd)<0)
{
perror("pipe()");
exit(1);
}
pid = fork();
if (pid<0)
{
perror("fork()");
exit(1);
}
if (pid == 0) //child read
{
close(pd[1]);//关闭写端
len = read(pd[0],buf,BUFSIZE);
write(1,buf,len);
close(pd[0]);
exit(0);
}
else //parent write
{
close(pd[0]);
write(pd[1],"Hello!",6);
close(pd[1]);
wait(NULL);
exit(0);
}
exit(0);
}
进程间通信
1台机器
1、管道
内核提供,单工通信,自同步机制,
匿名管道
int pipe(int pipefd[2]);//0端作为读端口,1端作为写端口
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFSIZE 1024
int main()
{
int pd[2],len = 0;
__pid_t pid;
int fd;
char buf[BUFSIZE];
if(pipe(pd)<0)
{
perror("pipe()");
exit(1);
}
pid = fork();
if (pid<0)
{
perror("fork()");
exit(1);
}
if (pid == 0) //child read
{
close(pd[1]);//关闭写端
dup2(pd[0],0);
close(pd[0]);
fd = open("/dev/null",O_RDWR);
dup2(fd,1);
dup2(fd,2);
execl("/usr/local/bin/mpg123","mpg123","-",NULL);
perror("execl()");
exit(1);
}
else //parent write
{
close(pd[0]); //关闭读端
//父进程从网上收取数据往管道当中写
close(pd[1]);
wait(NULL);
exit(0);
}
exit(0);
}
命名管道
mkfifo
2、XSI -> SysV
IPC -> Inter-Process Communication
主动端:先发包的一方。
被动端:先收包的一方 (先运行,等待收)。
key:ftok (使得双方拿到同一个key值)
消息队列
msgget(); msgsnd、msgrcv
msgop();
msgctl();
消息队列的实现
协议proto.h
#ifndef PROTO_H__
#define PROTO_H__
#define KEYPATH "/etc/services"
#define KEYPROJ 'g'
#define NAMESIZE 1024
struct msg_st
{
long mtype;
char name[NAMESIZE];
int math;
int chinese;
};
#endif // !PROTO_H__
接收端代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "proto.h"
int main()
{
key_t key;
int msgid;
struct msg_st rbuf;
key = ftok(KEYPATH,KEYPROJ);
if (key<0)
{
perror("ftok()");
exit(1);
}
//创建一个msg
msgid = msgget(key,IPC_CREAT|0600);
if (msgid < 0)
{
perror("msgget()");
exit(1);
}
while (1)
{
//接收 打印 接受 打印
if (msgrcv(msgid,&rbuf,sizeof(rbuf)-sizeof(long),0,0)<0)
{
perror("msgrcv()");
exit(1);
}
printf("NAME = %s\n",rbuf.name);
printf("MATH = %d\n ",rbuf.math);
printf("CHINESE = %d\n ",rbuf.chinese);
}
msgctl(msgid,IPC_RMID,NULL);
exit(0);
}
发送端代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include "proto.h"
int main()
{
key_t key;
struct msg_st sbuf;
int msgid;
key = ftok(KEYPATH,KEYPROJ);
if (key < 0)
{
perror("ftok()");
exit(1);
}
msgid = msgget(key,0);
if (msgid < 0)
{
perror("msgget()");
exit(1);
}
sbuf.mtype = 1;
strcpy(sbuf.name,"xiaohong");
sbuf.math = rand()%100;
sbuf.chinese = rand()%100;
if(msgsnd(msgid,&sbuf,sizeof(sbuf)- sizeof(long),0)<0)
{
perror("msgsnd()");
exit(1);
}
puts("OK!");
exit(0);
}
信号量数组
semget();
semop();
stmctl();
共享内存
shmget();
shmop();
shmctl();
多台机器
3、网络套接字socket