这里只是简单的举例来说明ipc通讯机制相关函数用法:
管道
===============================================================================
#include <unistd.h>
int pipe(int pipefides[]);
举例:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUF_SIZE 50
int main() {
pid_t pid;
char buf[BUF_SIZE] ={0};
int pfds[2] = {-1, -1};
if (pipe(pfds) < 0) {
perror("pipe error");
exit(0);
}
if ((pid = fork()) < 0) {
perror("fork error");
exit(0);
}
if (pid == 0) {
close(pfds[1]);
int len = 0;
while (len == 0) {
read(pfds[0], buf, BUF_SIZE);
len = strlen(buf);
}
printf("%s\n", buf);
close(pfds[0]);
exit(0);
}
close(pfds[0]);
strcpy(buf, "This is a pipe test!");
write(pfds[1], buf, BUF_SIZE);
close(pfds[1]);
sleep(2);
int status;
waitpid(-1, &status, 0);
if (WIFEXITED(status)) {
printf("child exit status %d", WEXITSTATUS(status));
}
return 0;
}
运行结果:
This is a pipe test!
child exit status 0
运行 FINISHED; 退出值0; 实时: 2s; 用户: 0ms; 系统: 0ms
===============================================================================
有名管道
===============================================================================
#include<sys/ipc.h>
#include <sys/stat.h>
int mkfifo (__const char *__path, __mode_t __mode);
举例:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <fcntl.h>
#include <sys/stat.h>
#define BUF_SIZE 50
#define PIPE_FILE_PATH "/tmp/pipe0"
int main() {
unlink(PIPE_FILE_PATH);
int fd;
pid_t pid;
char buf[BUF_SIZE] = {0};
if (mkfifo(PIPE_FILE_PATH, 0666) < 0) {
perror("mk fifo error");
exit(0);
}
if ((pid = fork()) < 0) {
perror("fork error");
exit(0);
}
if (pid == 0) {
int len = 0;
if ((fd = open(PIPE_FILE_PATH, O_RDONLY)) < 0) {
perror("open read failed");
exit(0);
}
while (len == 0) {
if (read(fd, buf, BUF_SIZE) < 0) {
exit(0);
}
len = strlen(buf);
}
printf("%s\n", buf);
close(fd);
exit(0);
}
if ((fd = open(PIPE_FILE_PATH, O_WRONLY)) < 0) {
perror("open write failed");
exit(0);
}
strcpy(buf, "This is a pipe test!");
write(fd, buf, BUF_SIZE);
close(fd);
sleep(2);
int status;
waitpid(-1, &status, 0);
if (WIFEXITED(status)) {
printf("child exit status %d", WEXITSTATUS(status));
}
return 0;
}
运行结果:
This is a pipe test!
child exit status 0
运行 FINISHED; 退出值0; 实时: 2s; 用户: 0ms; 系统: 0ms
===============================================================================
类似命令行管道(cat /etc/passwd|grep 'root')
===============================================================================
#include <stdio.h>
FILE *popen (__const char *__command, __const char *__modes)
int pclose (FILE *__stream);
举例说明:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/errno.h>
int main() {
char buf[2048];
FILE *pipe = popen("cat /etc/passwd","r");
fgets(buf,2048,pipe);//只读取一行
puts(buf);
return 0;
}
root:x:0:0:root:/root:/bin/bash
运行 FINISHED; 退出值0; 实时: 10ms; 用户: 0ms; 系统: 0ms
===============================================================================
消息队列
===============================================================================
#include<sys/ipc.h>
#include<sys/msg.h>
int msgctl (int msqid, int cmd, struct msqid_ds *buf);
int msgget (key_t key, int msgflg);
ssize_t msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg);
举例:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define MSG_KEY 1000ll
#define BUF_SIZE 50
typedef struct {
long msg_type;
char text[BUF_SIZE];
} Message;
#define MSG_TYPE 0x100al
int main() {
int msgid;
Message msg = {0};
if ((msgid = msgget(MSG_KEY, IPC_CREAT | 0666)) < 0) {
perror("creat msg id as 1000 error");
exit(0);
}
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork error");
exit(0);
}
if (pid == 0) {
msg.msg_type = MSG_TYPE;
memset(msg.text, 0, sizeof (msg.text));
strcpy(msg.text, "This is a test for msg queue!");
msgsnd(msgid, &msg, BUF_SIZE, 0);
exit(1);
}
if (waitpid(-1, NULL, 0) < 0) {
perror("wait error");
}
sleep(2);
msgrcv(msgid, &msg, BUF_SIZE, MSG_TYPE, 0);
printf("%s\n", msg.text);
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
运行结果:
This is a test for msg queue!
运行 FINISHED; 退出值0; 实时: 2s; 用户: 0ms; 系统: 0ms
===============================================================================