docker與宿主機(jī)共享內(nèi)存通信
docker中的進(jìn)程要與宿主機(jī)使用共享內(nèi)存通信,需要在啟動(dòng)容器的時(shí)候指定“–ipc=host”選項(xiàng)。然后再編寫(xiě)相應(yīng)的共享內(nèi)存的程序,一個(gè)跑在宿主機(jī)上,另一個(gè)跑在docker上面。
宿主機(jī)程序準(zhǔn)備
- shm_data.h
#ifndef _SHMDATA_H_HEADER
#define _SHMDATA_H_HEADER
#define TEXT_SZ 2048
struct shared_use_st
{
int written; // 作為一個(gè)標(biāo)志,非0:表示可讀,0:表示可寫(xiě)
char text[TEXT_SZ]; // 記錄寫(xiě)入 和 讀取 的文本
};
#endif
- shm_slave.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include "shmdata.h"
int main(int argc, char **argv)
{
void *shm = NULL;
struct shared_use_st *shared = NULL;
char buffer[BUFSIZ + 1]; // 用于保存輸入的文本
int shmid;
// 創(chuàng)建共享內(nèi)存
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}
// 將共享內(nèi)存連接到當(dāng)前的進(jìn)程地址空間
shm = shmat(shmid, (void *)0, 0);
if (shm == (void *)-1)
{
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
printf("Memory attched at %X\n", (int)shm);
// 設(shè)置共享內(nèi)存
shared = (struct shared_use_st *)shm;
while (1) // 向共享內(nèi)存中寫(xiě)數(shù)據(jù)
{
// 數(shù)據(jù)還沒(méi)有被讀取,則等待數(shù)據(jù)被讀取,不能向共享內(nèi)存中寫(xiě)入文本
while (shared->written == 1)
{
sleep(1);
printf("Waiting...\n");
}
// 向共享內(nèi)存中寫(xiě)入數(shù)據(jù)
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
strncpy(shared->text, buffer, TEXT_SZ);
// 寫(xiě)完數(shù)據(jù),設(shè)置written使共享內(nèi)存段可讀
shared->written = 1;
// 輸入了end,退出循環(huán)(程序)
if (strncmp(buffer, "end", 3) == 0)
{
break;
}
}
// 把共享內(nèi)存從當(dāng)前進(jìn)程中分離
if (shmdt(shm) == -1)
{
fprintf(stderr, "shmdt failed\n");
exit(EXIT_FAILURE);
}
sleep(2);
exit(EXIT_SUCCESS);
}
- makefile
all:
gcc -o shm_slave shm_slave.c
clean:
rm -rf shm_slave
docker鏡像準(zhǔn)備
- shm_data.h
#ifndef _SHMDATA_H_HEADER
#define _SHMDATA_H_HEADER
#define TEXT_SZ 2048
struct shared_use_st
{
int written; // 作為一個(gè)標(biāo)志,非0:表示可讀,0:表示可寫(xiě)
char text[TEXT_SZ]; // 記錄寫(xiě)入 和 讀取 的文本
};
#endif
- shm_master.c
#include <stddef.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "shmdata.h"
int main(int argc, char **argv)
{
void *shm = NULL;
struct shared_use_st *shared; // 指向shm
int shmid; // 共享內(nèi)存標(biāo)識(shí)符
// 將內(nèi)容寫(xiě)入到文件,可以通過(guò)查看文件確定共享內(nèi)存是否成功
FILE* file = fopen("t.txt","w+");
// 創(chuàng)建共享內(nèi)存
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666|IPC_CREAT);
if (shmid == -1)
{
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
// 將共享內(nèi)存連接到當(dāng)前進(jìn)程的地址空間
shm = shmat(shmid, 0, 0);
if (shm == (void *)-1)
{
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
printf("\nMemory attached at %X\n", (int)shm);
// 設(shè)置共享內(nèi)存
shared = (struct shared_use_st*)shm; // 注意:shm有點(diǎn)類(lèi)似通過(guò) malloc() 獲取到的內(nèi)存,所以這里需要做個(gè) 類(lèi)型強(qiáng)制轉(zhuǎn)換
shared->written = 0;
while (1) // 讀取共享內(nèi)存中的數(shù)據(jù)
{
// 沒(méi)有進(jìn)程向內(nèi)存寫(xiě)數(shù)據(jù),有數(shù)據(jù)可讀取
if (shared->written == 1)
{
printf("You wrote: %s", shared->text);
fputs(shared->text,file);
fflush(file);
sleep(1);
// 讀取完數(shù)據(jù),設(shè)置written使共享內(nèi)存段可寫(xiě)
shared->written = 0;
// 輸入了 end,退出循環(huán)(程序)
if (strncmp(shared->text, "end", 3) == 0)
{
break;
}
}
else // 有其他進(jìn)程在寫(xiě)數(shù)據(jù),不能讀取數(shù)據(jù)
{
sleep(1);
}
}
// 把共享內(nèi)存從當(dāng)前進(jìn)程中分離
if (shmdt(shm) == -1)
{
fprintf(stderr, "shmdt failed\n");
flcose(file);
exit(EXIT_FAILURE);
}
// 刪除共享內(nèi)存
if (shmctl(shmid, IPC_RMID, 0) == -1)
{
fprintf(stderr, "shmctl(IPC_RMID) failed\n");
fclose(file);
exit(EXIT_FAILURE);
}
flcose(file);
exit(EXIT_SUCCESS);
}
- makefile
all:
gcc -o shm_master shm_master.c
clean:
rm -rf shm_master
- Dockerfile
FROM gcc:latest
RUN mkdir /usr/src/shm_test
COPY shm_master.c shm_data.h makefile /usr/src/shm_test/
WORKDIR /usr/src/shm_test
RUN make
CMD ["./shm_master"]
運(yùn)行
運(yùn)行時(shí)需要先下載docker,獲取支持c語(yǔ)言編譯運(yùn)行的基礎(chǔ)鏡像,比如ubuntu、gcc等。這里使用gcc作為基礎(chǔ)鏡像。
sudo apt install docker
sudo docker pull gcc
# 查看一下gcc的鏡像是否拉取下來(lái)了
docker images
基礎(chǔ)鏡像有了后就可以基于基礎(chǔ)鏡像構(gòu)建docker容器,基于上面所寫(xiě)的dockerfile,構(gòu)建鏡像:
sudo docker build -t shm_master:v1 .
# 查看鏡像是否創(chuàng)建成功
sudo docker images
鏡像創(chuàng)建成功后就可以啟動(dòng)容器,啟動(dòng)時(shí)記得加上參數(shù)“–ipc”。
# fe9c3bd6d102是之前創(chuàng)建成功的鏡像的id
sudo docker run -d --ipc=host --name master fe9c3bd6d102
成功啟動(dòng)容器后可以進(jìn)入到容器內(nèi)部查看通信相關(guān)信息。
sudo docker exec -it master /bin/bash
reference
需要特別說(shuō)明的是:以下共享內(nèi)存的代碼均來(lái)自博客,在此表示感謝。docker鏡像創(chuàng)建參考自北極之光的博客。
-
https://www.cnblogs.com/hailun1987/p/9697236.html
-
https://www.jianshu.com/p/7eb7c7f62bf3文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-729598.html
-
https://www.cnblogs.com/52php/p/5861372.html文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-729598.html
到了這里,關(guān)于docker與宿主機(jī)共享內(nèi)存通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!