pipe
创建管道要在创建子进程之前
创建管道
其中fd[1]用来往管道里写,fd[1]用来向管道中读
向管道中写
1 write(fd1[1 ], inLine, LENGTH);
fd[1]表示现在是写,inLine是写入管道字符串的字符数组,LENGTH是写入的长度(一般和写入的长度相同)
从管道中读
1 read(fd2[0], outLine, LENGTH);
fd2[0]表示现在是读,outLine是从保存从管道中读取的字符数组,LENGTH是从管道中读取的长度
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define LENGTH 1024 int main () { int fd1[2 ]; char outLine[LENGTH]; int fd2[2 ]; char inLine[LENGTH]; pipe(fd1); pid_t p1 = fork(); if (p1 == -1 ) { printf ("create p1 failed\n" ); } else if (p1 == 0 ) { sprintf (inLine, "Child 1 is sending a message!" ); write(fd1[1 ], inLine, LENGTH); exit (0 ); } else { read(fd1[0 ], outLine, LENGTH); printf ("%s\n" , outLine); pipe(fd2); pid_t p2 = fork(); if (p2 == -1 ) { printf ("create p2 failed\n" ); } else if (p2 == 0 ) { sprintf (inLine, "Child 2 is sending a message!" ); write(fd2[1 ], inLine, LENGTH); exit (0 ); } else { read(fd2[0 ], outLine, LENGTH); printf ("%s\n" , outLine); } return 0 ; } return 0 ; }
消息队列
写入消息队列
创建消息队列
创建消息结构体,定义一个全局的消息结构体
1 2 3 4 struct msgbuf { long mtype; char mtext[LENGTH]; }msgbuf;
再在全局定义一个消息队列的键,这个键就是表示消息队列的编号
然后利用msgget创建消息队列
1 msgNum = msgget(MSG_KEY, IPC_CREAT | 0666 );
详细解释:
MSG_KEY作用:
MSG_KEY
应该是一个用于唯一标识消息队列的键值,但是它在代码中并没有被定义。通常情况下,可以使用
ftok()
函数来生成一个唯一的键值
IPC_CREAT作用
IPC_CREAT
表示如果消息队列不存在则创建
0666作用
表示消息队列的权限
在 Linux/Unix
中,文件权限通常以八进制数表示。每个权限对应的数值如下:
0
:没有任何权限
1
:执行权限(可执行文件)
2
:写权限(写入文件)
4
:读权限(读取文件)
这些权限可以组合使用,通过将对应的数值相加来表示多个权限的组合。例如:
3
:执行权限和写权限(1 + 2)
5
:执行权限和读权限(1 + 4)
6
:写权限和读权限(2 + 4)
7
:执行权限、写权限和读权限(1 + 2 + 4)
在 0666
中,表示的权限是:
0
:表示特殊权限位,通常为文件类型或文件特性(如设备文件、管道、套接字等),在这里不涉及文件类型的权限,因此这个位置通常用0填充。
666
:表示读权限和写权限,即文件的所有者、所属组和其他用户都有读和写的权限。
整条语句的作用是用来创建消息队列,
可以理解返回的是消息队列的地址
将缓存中消息发送到消息队列
1 msgsnd(msgNum, &msgbuf, LENGTH, 0 );
msNum
:消息队列的标识符,它是由 msgget
函数返回的值。
&msgbuf
:一个指向消息缓冲区的指针,消息将从这个缓冲区中发送。
1024
:消息的大小,以字节为单位。在这里,消息的大小为
1024 字节。
0
:这是一个标志参数,用于指定在发送消息时的行为。在这里,它是一个控制参数,通常可以用来设置一些特殊的行为,但在这个例子中被设置为
0,表示没有设置特殊的行为。
代码
1 2 3 4 5 6 7 8 9 10 void client () { msgNum = msgget(MSG_KEY, IPC_CREAT | 0666 ); printf ("input a message\n" ); scanf ("%s" , msgbuf.mtext); msgbuf.mtype = 1 ; msgsnd(msgNum, &msgbuf, LENGTH, 0 ); }
从消息队列中读取
获取消息队列
1 msgNum = msgget(MSG_KEY, IPC_CREAT | 0666 );
从消息队列中读取
1 msgrcv(msgNum, &msgbuf, LENGTH, 0 , 0 );
msgNum
:消息队列的标识符,它是由 msgget()
函数返回的值。
&msgbuf
:一个指向消息缓冲区的指针,用于存储接收到的消息。
LENGTH
:消息的最大长度,以字节为单位。在这里,消息的最大长度被设置为
1024 字节。
0
:这是一个消息的类型,它指定了要接收的消息的类型。在这里,设置为
0 表示接收队列中的第一个消息。
0
:这是一个标志参数,用于指定在接收消息时的行为。在这里,它是一个控制参数,表示没有设置特殊的行为。
代码
1 2 3 4 5 6 void server () { msgNum = msgget(MSG_KEY, IPC_CREAT | 0666 ); msgrcv(msgNum, &msgbuf, LENGTH, 0 , 0 ); printf ("The save line is %s\n" , msgbuf.mtext); msgctl(msgNum, IPC_RMID, 0 ); }
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/msg.h> #include <sys/ipc.h> #include <wait.h> #include <stdlib.h> #define LENGTH 1024 #define MSG_KEY 24 struct msgbuf { long mtype; char mtext[LENGTH]; }msgbuf; int msgNum = 0 ; void client () { msgNum = msgget(MSG_KEY, IPC_CREAT | 0666 ); printf ("input a message\n" ); scanf ("%s" , msgbuf.mtext); msgbuf.mtype = 1 ; msgsnd(msgNum, &msgbuf, LENGTH, 0 ); } void server () { msgNum = msgget(MSG_KEY, IPC_CREAT | 0666 ); msgrcv(msgNum, &msgbuf, LENGTH, 0 , 0 ); printf ("The save line is %s\n" , msgbuf.mtext); msgctl(msgNum, IPC_RMID, 0 ); } int main () { pid_t p1 = fork(); if (p1 == -1 ) { printf ("create p1 failed\n" ); } else if (p1 == 0 ) { wait(0 ); printf ("this is child process1\n" ); server(); printf ("process1 end\n" ); } else { pid_t p2 = fork(); if (p2 == -1 ) { printf ("create p2 failed\n" ); } else if (p2 == 0 ) { printf ("this is child process2\n" ); client(); printf ("process2 end\n" ); } else { wait(0 ); printf ("task end\n" ); } } return 0 ; }