1、将消息队列发送接收端实现一遍。
实现消息队列发送和接收的过程:
- 生成唯一键值对:使用
ftok()
函数,根据文件路径(或常量字符串)和整数生成一个唯一的 键值 (key
)。 - 根据唯一键值对创建唯一标识符队列:使用
msgget()
函数,通过该键值创建或获取一个消息队列,并指定队列的权限,返回消息队列的唯一标识符 队列ID (msgid
)。 - 收发消息:使用
msgsnd()
函数通过队列ID发送消息,或者使用msgrcv()
函数接收消息。
函数解释:
-
ftok()
:ftok
(file to key) 用于生成唯一的键值 (key
)。- 参数1: 一个文件路径或常量字符串,作为键值的标识符。
- 参数2: 一个整数,通常为项目标识符,用于增强唯一性。
-
msgget()
:msgget
(message get) 用于根据键值创建或获取消息队列。- 参数1: 由
ftok()
生成的键值 (key
)。 - 参数2: 消息队列的权限标志,指定文件权限(例如
0666
)。 - 返回值: 返回消息队列的唯一标识符 (
msgid
),用于后续操作。
- 参数1: 由
-
msgsnd()
:msgsnd
(message send) 用于发送消息到指定的消息队列。- 参数1: 消息队列的唯一标识符 (
msgid
)。 - 参数2: 消息数据的地址,指向要发送的消息结构。
- 参数3: 消息数据的大小。
- 参数4: 操作标志,通常为
0
,表示默认行为。
- 参数1: 消息队列的唯一标识符 (
-
msgrcv()
:msgrcv
(message receive) 用于从指定的消息队列中接收消息。- 参数1: 消息队列的唯一标识符 (
msgid
)。 - 参数2: 接收消息的缓冲区地址。
- 参数3: 接收消息的最大大小。
- 参数4: 消息类型,指定接收哪种类型的消息(由发送时定义)。
- 参数5: 操作标志,通常为
0
,表示默认行为。
- 参数1: 消息队列的唯一标识符 (
发送端:
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msg_buf{
long msg_type;
char msg_text[100];
};
int main(int argc, const char *argv[])
{
key_t key;
int msg_id;
struct msg_buf send_message;
key=ftok("pro",'A');
msg_id=msgget(key,0666|IPC_CREAT);
send_message.msg_type=1;
strcpy(send_message.msg_text,"hello");
msgsnd(msg_id,&send_message,sizeof(send_message),0);
printf("发送成功,发送的数据为%s\n",send_message.msg_text);
return 0;
}
接收端:
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msg_buf{
long msg_type;
char msg_text[100];
};
int main(int argc, const char *argv[])
{
key_t key;
int msg_id;
struct msg_buf get_message;
key=ftok("pro",'A');
msg_id=msgget(key,0666|IPC_CREAT);
msgrcv(msg_id,&get_message,sizeof(get_message),1,0);
printf("接受到的消息是msg%s\n",get_message.msg_text);
return 0;
}
2、将共享内存发送接收实现一遍。
实现共享内存收发消息的过程:
- 使用
ftok()
函数,根据文件路径(或常量字符串)和整数生成一个唯一的 键值 (key
)。 - 使用
shmget()
函数,通过该键值创建或获取一块共享内存,指定共享内存的大小和权限,返回共享内存的唯一标识符 内存段ID (shmid
)。 - 使用
shmat()
函数将共享内存附加到调用进程的地址空间,从而获取指向共享内存的指针。 - 使用该指针读取或写入共享内存中的数据。
- 使用
shmdt()
函数将共享内存从调用进程的地址空间分离。 - 最后,使用
shmctl()
函数,可以删除共享内存(可选)。
函数解释:
-
ftok()
:ftok
(file to key) 用于生成唯一的键值 (key
)。- 参数1: 一个文件路径或常量字符串,作为键值的标识符。
- 参数2: 一个整数,用于增强唯一性。
-
shmget()
:shmget
(shared memory get) 用于根据键值创建或获取一块共享内存。- 参数1: 由
ftok()
生成的键值 (key
)。 - 参数2: 要分配的共享内存的大小(以字节为单位)。
- 参数3: 共享内存的权限标志,类似文件权限(例如
0666
)。 - 返回值: 返回共享内存的唯一标识符 (
shmid
),用于后续操作。
- 参数1: 由
-
shmat()
:shmat
(shared memory attach) 用于将共享内存附加到调用进程的地址空间。- 参数1: 共享内存的唯一标识符 (
shmid
)。 - 参数2: 通常为
NULL
,表示让操作系统自动选择共享内存的附加地址。 - 参数3: 操作标志,通常为
0
,表示默认行为。 - 返回值: 返回指向共享内存的指针,用于读写数据。
- 参数1: 共享内存的唯一标识符 (
-
shmdt()
:shmdt
(shared memory detach) 用于将共享内存从调用进程的地址空间分离。- 参数1: 指向共享内存的指针。
-
shmctl()
:shmctl
(shared memory control) 用于控制共享内存段的行为,例如删除共享内存。- 参数1: 共享内存的唯一标识符 (
shmid
)。 - 参数2: 控制命令,例如
IPC_RMID
用于删除共享内存段。 - 参数3: 一个指向
shmid_ds
结构的指针,通常在删除时为NULL
。
- 参数1: 共享内存的唯一标识符 (
发送端:
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, const char *argv[])
{
key_t key;
int mes_id;
char *share_buf;
key=ftok("share",'A');
mes_id=shmget(key,1024,0666|IPC_CREAT);
share_buf=(char*)shmat(mes_id,NULL,0);
strcpy(share_buf,"hello");
printf("发送数据为%s\n",share_buf);
shmdt(mes_id);
return 0;
}
发送端:
#include <stdio.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, const char *argv[])
{
key_t key;
int mes_id;
char *message;
key=ftok("share",'A');
mes_id=shmget(key,1024,0666|IPC_CREAT);
message=(char*)shmat(mes_id,NULL,0);
printf("接受到的数据为%s",message);
shmdt(mes_id);
return 0;
}
3、建立两个.c建立子父进程,父进程发送消息到队列,子进程读取队列,另一个同样。
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int pid;
key_t key;
int share_id;
key=ftok("share",'A');
share_id=shmget(key,1024,0666|IPC_CREAT);
pid=fork();
if(pid<0){
printf("进程创建失败");
return -1;
}else if(pid>0){
char *send;
send=(char*)shmat(share_id,NULL,0);
strcpy(send,"comefrom parent");
printf("发送的消息%s\n",send);
shmdt(send);
wait(NULL);
}else{
sleep(1);
char *get;
get=(char*)shmat(share_id,NULL,0);
printf("接受到的消息%s\n",get);
shmdt(get);
exit(0);
}
return 0;
}