进程间通信IPC
Internet Process Connection
管道
有名管道
信号量
消息队列
信号
共享内存
套接字
管道:一种两个进程间进行单向通信的机制。半双工管道
只能用于父子或兄弟
管道的创建
#include <unistd.h>
int pipe(int fd[2]);
fd[0]管道读端
fd[1]写
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
void read_from_pipe(int fd)
{
char message[100];
read(fd , message,100);
printf("read from pipe:%s\n",message);
}
void write_to_pipe(int fd)
{
char *message = "Hello,pipe!\n";
write(fd,message,strlen(message)+1);
}
int main()
{
int fd[2];
pid_t pid;
int stat_val;
if(pipe(fd))
{
printf("create pipe failed!\n");
exit(1);
}
pid = fork();
switch(pid)
{
case -1:
printf("fork error!\n");
exit(1);
case 0:
close(fd[1]);
read_from_pipe(fd[0]);
exit(0);
default:
close(fd[0]);
write_to_pipe(fd[1]);
wait(&stat_val);
exit(0);
}
return 0;
}
有名管道named pipe/FIFO
创建
#include <sys/types.h>
#include <sys/stat.h>
int mknod(const char* path,mode_t mod,dev_t dev);
int mkfifo(const char *path,mode_t mod);
umask(0);
if(mknod("/tmp/fifo",S_IFIFO | 0666,0) == -1)
{
perror("mknod error!");
exit(1);
}
if(mkfifo("/tmp/fifo",S_IFIFO | 0666) == -1)
{
perror("mkfifo error!");
exit(1);
}
有名管道是一个存在于硬盘上的文件
管道是存在于内存中的特殊文件
消息队列是一个存在内核中的消息链表,每个消息队列由消息队列标识符标识。
消息缓冲结构
#include <linux/msg.h>
struct msgbuf
{
long mtype;
char mtext[1];
};
创建
#include <sys/types.h>
#include <ipc.h>
key_t ftok(const char* pathname,int proj_id);
根据pathname,proj_id生成唯一的键值。
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
int main()
{
int i ;
for(i = 1;i<=5;i++)
{
printf("key[%d] = %ul \n",i,ftok(".",i));
exit(0);
}
}
创建一个新消息队列或访问一个已存在的消息队列
int msgget(key_t key,int msgflg);
写队列
int msgsnd(int msqid,struct msgbuf* msgp,size_t msgsz,int magflg);
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUF_SIZE 256
#define PROJ_ID 32
#define PATH_NAME "."
int main()
{
struct mymsgbuf
{
long msgtype;
char ctrlstring[BUF_SIZE];
}msgbuffer;
int qid;
int msglen;
int msgkey;
if((msgkey = ftok(PTAH_NAME,PROJ_ID)) == -1)
{
perror("ftok error\n");
exit(1);
}
if((qid = msgget(msgkey,IPC_CREAT| 0660)) == -1)
{
perror("msgget error!\n");
exit(1);
}
msgbuffer.msgtype = 3;
strcpy(msgbuffer.ctrlstring,"Hello,message queue");
msglen = sizeof(struct mymsgbuff) = 4;
if(msgsnd(qid,*msgbuffer,msglen,0) == -1)
{
perror("msgget error!\n");
exit(1);
}
exit(0);
}
读消息队列
int msgrcv(int msqid,struct msgbuf *msgp,size_t msgsz,long int msgtyp,int msgflg);
信号量
#include <sys/sem.h>
int semget(key_t key,int nsems,int semflg);
int semop(int semid,struct sembuf* sops,size_t nsops);
int semctl(int semid,int semnum,int cmd,...);
共享内存
分配一块能被其他进程访问的内存
#include <linux/shm.h>
int shmget(key_t key,size_t size,int shmflg);
Internet Process Connection
管道
有名管道
信号量
消息队列
信号
共享内存
套接字
管道:一种两个进程间进行单向通信的机制。半双工管道
只能用于父子或兄弟
管道的创建
#include <unistd.h>
int pipe(int fd[2]);
fd[0]管道读端
fd[1]写
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
void read_from_pipe(int fd)
{
char message[100];
read(fd , message,100);
printf("read from pipe:%s\n",message);
}
void write_to_pipe(int fd)
{
char *message = "Hello,pipe!\n";
write(fd,message,strlen(message)+1);
}
int main()
{
int fd[2];
pid_t pid;
int stat_val;
if(pipe(fd))
{
printf("create pipe failed!\n");
exit(1);
}
pid = fork();
switch(pid)
{
case -1:
printf("fork error!\n");
exit(1);
case 0:
close(fd[1]);
read_from_pipe(fd[0]);
exit(0);
default:
close(fd[0]);
write_to_pipe(fd[1]);
wait(&stat_val);
exit(0);
}
return 0;
}
有名管道named pipe/FIFO
创建
#include <sys/types.h>
#include <sys/stat.h>
int mknod(const char* path,mode_t mod,dev_t dev);
int mkfifo(const char *path,mode_t mod);
umask(0);
if(mknod("/tmp/fifo",S_IFIFO | 0666,0) == -1)
{
perror("mknod error!");
exit(1);
}
if(mkfifo("/tmp/fifo",S_IFIFO | 0666) == -1)
{
perror("mkfifo error!");
exit(1);
}
有名管道是一个存在于硬盘上的文件
管道是存在于内存中的特殊文件
消息队列是一个存在内核中的消息链表,每个消息队列由消息队列标识符标识。
消息缓冲结构
#include <linux/msg.h>
struct msgbuf
{
long mtype;
char mtext[1];
};
创建
#include <sys/types.h>
#include <ipc.h>
key_t ftok(const char* pathname,int proj_id);
根据pathname,proj_id生成唯一的键值。
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
int main()
{
int i ;
for(i = 1;i<=5;i++)
{
printf("key[%d] = %ul \n",i,ftok(".",i));
exit(0);
}
}
创建一个新消息队列或访问一个已存在的消息队列
int msgget(key_t key,int msgflg);
写队列
int msgsnd(int msqid,struct msgbuf* msgp,size_t msgsz,int magflg);
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUF_SIZE 256
#define PROJ_ID 32
#define PATH_NAME "."
int main()
{
struct mymsgbuf
{
long msgtype;
char ctrlstring[BUF_SIZE];
}msgbuffer;
int qid;
int msglen;
int msgkey;
if((msgkey = ftok(PTAH_NAME,PROJ_ID)) == -1)
{
perror("ftok error\n");
exit(1);
}
if((qid = msgget(msgkey,IPC_CREAT| 0660)) == -1)
{
perror("msgget error!\n");
exit(1);
}
msgbuffer.msgtype = 3;
strcpy(msgbuffer.ctrlstring,"Hello,message queue");
msglen = sizeof(struct mymsgbuff) = 4;
if(msgsnd(qid,*msgbuffer,msglen,0) == -1)
{
perror("msgget error!\n");
exit(1);
}
exit(0);
}
读消息队列
int msgrcv(int msqid,struct msgbuf *msgp,size_t msgsz,long int msgtyp,int msgflg);
信号量
#include <sys/sem.h>
int semget(key_t key,int nsems,int semflg);
int semop(int semid,struct sembuf* sops,size_t nsops);
int semctl(int semid,int semnum,int cmd,...);
共享内存
分配一块能被其他进程访问的内存
#include <linux/shm.h>
int shmget(key_t key,size_t size,int shmflg);
void* shmat(int shmid,const void *shmaddr,int shmflg);