# linux ipc
很讚的筆記https://jasonblog.github.io/note/linux_system/linux_xia_ipc_de_yun_zuo_fang_shi.html
https://hackmd.io/@sysprog/linux-shared-memory
https://yayaya6d.pixnet.net/blog/post/350095123-linus%E5%90%84%E7%A8%AE%E9%9B%9C%E8%AB%87--process%E9%96%93%E7%9A%84%E6%BA%9D%E9%80%9A%EF%BC%9Amsg-queue
## shard_memory
### server
```c=
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#define SHMSZ 27
int main()
{
char c;
int shmid;
key_t key;
char* shm, *s;
/*
* We'll name our shared memory segment
* "5678".
*/
key = 5678;
/*
* Create the segment.
*/
if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit(1);
}
/*
* Now we attach the segment to our data space.
*/
if ((shm = shmat(shmid, NULL, 0)) == (char*) - 1) {
perror("shmat");
exit(1);
}
/*
* Now put some things into the memory for the
* other process to read.
*/
s = shm;
for (c = 'a'; c <= 'z'; c++) {
*s++ = c;
}
*s = NULL;
/*
* Finally, we wait until the other process
* changes the first character of our memory
* to '*', indicating that it has read what
* we put there.
*/
while (*shm != '*') {
sleep(1);
}
exit(0);
}
```
### client
```c=
/*
* shm-client - client program to demonstrate shared memory.
*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#define SHMSZ 27
main()
{
int shmid;
key_t key;
char* shm, *s;
/*
* We need to get the segment named
* "5678", created by the server.
*/
key = 5678;
/*
* Locate the segment.
*/
if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {
perror("shmget");
exit(1);
}
/*
* Now we attach the segment to our data space.
*/
if ((shm = shmat(shmid, NULL, 0)) == (char*) - 1) {
perror("shmat");
exit(1);
}
/*
* Now read what the server put in the memory.
*/
for (s = shm; *s != NULL; s++) {
putchar(*s);
}
putchar('\n');
/*
* Finally, change the first character of the
* segment to '*', indicating we have read
* the segment.
*/
*shm = '*';
exit(0);
}
```
```
root@HOME-X213212:~/leetcode-1# ipcs
------ Message Queues --------
key msqid owner perms used-bytes messages
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0000162e 0 root 666 27 0
------ Semaphore Arrays --------
key semid owner perms nsems
```
```
./client
root@HOME-X213212:~/leetcode-1/ipc/shardmemory# ./client
*bcdefghijklmnopqrstuvwxyz
```
## message queue
### server
```c=
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
// 用于创建一个唯一的key
#define MSG_FILE "/etc/passwd"
// 消息结构
struct msg_form {
long mtype;
char mtext[256];
};
int main()
{
int msqid;
key_t key;
struct msg_form msg;
// 获取key值
if((key = ftok(MSG_FILE,'z')) < 0)
{
perror("ftok error");
exit(1);
}
// 打印key值
printf("Message Queue - Server key is: %d.\n", key);
// 创建消息队列
if ((msqid = msgget(key, IPC_CREAT|0777)) == -1)
{
perror("msgget error");
exit(1);
}
// 打印消息队列ID及进程ID
printf("My msqid is: %d.\n", msqid);
printf("My pid is: %d.\n", getpid());
// 循环读取消息
for(;;)
{
msgrcv(msqid, &msg, 256, 888, 0);// 返回类型为888的第一个消息
printf("Server: receive msg.mtext is: %s.\n", msg.mtext);
printf("Server: receive msg.mtype is: %d.\n", msg.mtype);
msg.mtype = 999; // 客户端接收的消息类型
sprintf(msg.mtext, "hello, I'm server %d", getpid());
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
}
return 0;
}
```
### client
```c=
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
// 用于创建一个唯一的key
#define MSG_FILE "/etc/passwd"
// 消息结构
struct msg_form {
long mtype;
char mtext[256];
};
int main()
{
int msqid;
key_t key;
struct msg_form msg;
// 获取key值
if ((key = ftok(MSG_FILE, 'z')) < 0)
{
perror("ftok error");
exit(1);
}
// 打印key值
printf("Message Queue - Client key is: %d.\n", key);
// 打开消息队列
if ((msqid = msgget(key, IPC_CREAT|0777)) == -1)
{
perror("msgget error");
exit(1);
}
// 打印消息队列ID及进程ID
printf("My msqid is: %d.\n", msqid);
printf("My pid is: %d.\n", getpid());
// 添加消息,类型为888
msg.mtype = 888;
sprintf(msg.mtext, "hello, I'm client %d", getpid());
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
// 读取类型为777的消息
msgrcv(msqid, &msg, 256, 999, 0);
printf("Client: receive msg.mtext is: %s.\n", msg.mtext);
printf("Client: receive msg.mtype is: %d.\n", msg.mtype);
return 0;
}
```
```
------ Message Queues --------
key msqid owner perms used-bytes messages
0x7a202919 0 root 777 0 0
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x0000162e 0 root 666 27 0
------ Semaphore Arrays --------
key semid owner perms nsems
```
server
```bash=
root@HOME-X213212:~/leetcode-1/ipc/messagequeue# ./server
Message Queue - Server key is: 2048928025.
My msqid is: 0.
My pid is: 17918.
Server: receive msg.mtext is: hello, I'm client 17946.
Server: receive msg.mtype is: 888.
```
client
```bash=
root@HOME-X213212:~/leetcode-1/ipc/messagequeue# ./client
Message Queue - Client key is: 2048928025.
My msqid is: 0.
My pid is: 17946.
Client: receive msg.mtext is: hello, I'm server 17918.
Client: receive msg.mtype is: 999.
```