管道
管道式通过调用pipe()函数创建的,若成功返回0,若出错返回-1。
int pipe(int fd[2]);
经由参数fd返回两个文件描述符:fd[0]为而打开,fd[1]为写而打开,fd[1]的输出是fd[0]的输入。
//创建一个子进程到父进程的管道,子进程经由该管道向父进程传送数据
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( void ) {
int fds[2];
pipe(fds);
pid_t pid = fork();
if ( pid == 0 ) {
close(fds[0]); // 关闭管道读
sleep(2);
write(fds[1], "abc", 3);
close(fds[1]);
} else {
close(fds[1]);
char buf[12] = {};
read(fds[0], buf, 12);
close(fds[0]);
printf("parent : %s\n" ,buf);
}
}
/*------------------------------------
parent : abc
*/
消息队列
消息队列是消息的链接表,存储在内核中有消息对列标识符标识。消息队列是一个跨进程的队列,一个进程将数据放入队列,另一个进程从消息队列中取出数据。
- ipcs -q 查看消息队列
创建一个消息队列。[注]创建消息队列的进程结束了,消息队列也应该存在。
int msgget(key_t key, int msgflg)
flag:如果是打开消息队列,填写0;如果是创建消息队列IPC_CREATE|0644;
创建消息队列1234
int main( void ) {
int id = msgget(1234, IPC_CREAT|0644);
if ( id == -1 ) perror("msgget"),exit(1);
printf("msgget ok\n");
}
调用msgsnd将消息放入消息队列中。
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgp一般为以下结构体
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
发送消息
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf {
long channel;
char buf[100];
};
int main( void ) {
int id = msgget(1234, 0);
struct msgbuf mb;
printf("channel:");
scanf("%d", &mb.channel);
printf("msg:");
scanf("%s", &mb.buf);
if ( msgsnd(id, &mb, strlen(mb.buf), 0) == -1 )
perror("msgsnd"),exit(1);
}
/*----------------------------------------
channel:3
msg:abc
*/
msgrcv从消息队列中取用消息。
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
参数type可以指定要哪一种消息:
type==0 返回队列中第一个消息
type>0 返回队列中第一个type类型的消息
取用消息
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf {
long channel;
char buf[100];
};
int main( void ) {
int id = msgget(1234, 0);
struct msgbuf mb;
long c;
memset(&mb, 0x00, sizeof(mb));
printf("你想读取哪个通道的数据:");
scanf("%ld", &c);
msgrcv(id, &mb, 100, c, 0);
printf("%s\n", mb.buf);
}
/*------------------------------------------------------
你想读取哪个通道的数据:3
abc
*/
msgctl对队列执行多种操作
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
删除消息队列:msgctl(id, IPC_PMID, NULL);