当前位置: 首页 > wzjs >正文

网站改版不收录上辽宁建设工程信息网站

网站改版不收录,上辽宁建设工程信息网站,新手如何搭建网站,网站建设管理办法【Linux学习笔记】进程间通信之共享内存 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 文章目录 【Linux学习笔记】进程间通信之共享内存前言一. system V共享内存1.1 共享内存数据结构1.2 共享内存函数1.3 共享内存实现通信…

【Linux学习笔记】进程间通信之共享内存

在这里插入图片描述

🔥个人主页大白的编程日记

🔥专栏Linux学习笔记


文章目录

  • 【Linux学习笔记】进程间通信之共享内存
    • 前言
    • 一. system V共享内存
      • 1.1 共享内存数据结构
      • 1.2 共享内存函数
      • 1.3 共享内存实现通信
      • 1.4 借助管道实现访问控制版的共享内存
    • 后言

前言

哈喽,各位小伙伴大家好!上期我们讲了进程间通信之管道 今天我们讲的是进程间通信之共享内存。话不多说,我们进入正题!向大厂冲锋!
在这里插入图片描述

一. system V共享内存

共享内存区是最快的IPC形式。⼀旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执⾏进⼊内核的系统调⽤来传递彼此的数据

共享内存示意图

在这里插入图片描述

1.1 共享内存数据结构

struct shmid_ds {
struct ipc_perm shm_perm; /* operation perms */
int shm_segsz; /* size of segment
(bytes) */
__kernel_time_t shm_atime; /* last attach time */
__kernel_time_t shm_dtime; /* last detach time */
__kernel_time_t shm_ctime; /* last change time */
__kernel_ipc_pid_t shm_cpid; /* pid of creator */
__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
unsigned short shm_nattch; /* no. of current
attaches */
unsigned short shm_unused; /* compatibility */
void shm_unused2; / ditto - used by
DIPC */
void shm_unused3; / unused */
};

1.2 共享内存函数

shmget函数

功能:⽤来创建共享内存
原型
int shmget(key_t key, size_t size, int shmflg);
参数
key:这个共享内存段名字
size:共享内存⼤⼩
shmflg:由九个权限标志构成,它们的⽤法和创建⽂件时使⽤的mode模式标志是⼀样的
取值为IPC_CREAT:共享内存不存在,创建并返回;共享内存已存在,获取并返回。
取值为IPC_CREAT | IPC_EXCL:共享内存不存在,创建并返回;共享内存已存在,出
错返回。
返回值:成功返回⼀个⾮负整数,即该共享内存段的标识码;失败返回-1

shmat函数

功能:将共享内存段连接到进程地址空间
原型
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
shmid: 共享内存标识
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回⼀个指针,指向共享内存第⼀个节;失败返回-1

说明:

shmaddr为NULL,核⼼⾃动选择⼀个地址
shmaddr不为NULL且shmflg⽆SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会⾃动向下调整为SHMLBA的整数倍。
公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表⽰连接操作⽤来只读共享内存

shmdt函数

功能:将共享内存段与当前进程脱离
原型
int shmdt(const void *shmaddr);
参数
shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

shmctl函数

功能:⽤于控制共享内存
原型
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向⼀个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

在这里插入图片描述

1.3 共享内存实现通信

测试代码结构

# ls
client.c comm.c comm.h Makefile server.c
# cat Makefile
.PHONY:all
all:server client
client:client.c comm.c
gcc -o $@ $^
server:server.c comm.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f client server
1

comm.h

#ifndef _COMM_H_
#define _COMM_H_
# include <stdio.h>
# include <sys/types.h>
# include <sys/ipc.h>
# include <sys/shm.h>
# define PATHNAME "."
# define PROJ_ID 0x6666
int createShm(int size);
int destroyShm(int shmid);
int getShm(int size);
# endif

comm.c

#include "comm.h"
static int commShm(int size, int flags)
{
key_t key = ftok(PATHNAME, PROJ_ID);
if(key < 0){
perror("ftok");
return -1;
}
int shmid = 0;
if( (shmid = shmget(key, size, flags)) < 0){
perror("shmget");
return -2;
}
return shmid;
}
int destroyShm(int shmid)
{
if(shmctl(shmid, IPC_RMID, NULL) < 0){
perror("shmctl");
return -1;
}
return 0;
}
int createShm(int size)
{
return commShm(size, IPC_CREAT|IPC_EXCL|0666);
}
int getShm(int size)
{
return commShm(size, IPC_CREAT);
}

server.c

#include "comm.h"
int main()
{
int shmid = createShm(4096);
char *addr = shmat(shmid, NULL, 0);
sleep(2);
int i = 0;
while(i++<26){
printf("client# %s\n", addr);
sleep(1);
}
shmdt(addr);
sleep(2);
destroyShm(shmid);
return 0;
}

client.c

#include "comm.h"
int main()
{
int shmid = getShm(4096);
sleep(1);
char *addr = shmat(shmid, NULL, 0);
sleep(2);
int i = 0;
while(i<26){
addr[i] = 'A'+i;
i++;
addr[i] = 0;
sleep(1);
}
shmdt(addr);
sleep(2);
return 0;
}

1.4 借助管道实现访问控制版的共享内存

在这里插入图片描述

  • Comm.hpp
以下是提取的代码:```cpp
#pragma once#include <fcntl.h>#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <cstring>
#include <iostream>
#include <string>using namespace std;#define Debug 0
#define Notice 1
#define Warning 2
#define Error 3
const std::string msg[] = {"Debug","Notice","Warning","Error"
};std::ostream &Log(std::string message, int level) {std::cout << " | " << (unsigned)time(nullptr) << " | " << msg[level] << " | " << message;return std::cout;
}#define PATH_NAME "/home/hyb"
#define PROJ_ID 0x66
#define SHM_SIZE 4096  // 共享内存的大小,最好是页(PAGE: 4096)的整数倍
#define FIFO_NAME "./fifo"class Init {
public:Init() {umask(0);int n = mkfifo(FIFO_NAME, 0666);assert(n == 0);(void)n;Log("create fifo success", Notice) << "\n";}~Init() {unlink(FIFO_NAME);Log("remove fifo success", Notice) << "\n";}
};#define READ O_RDONLY
#define WRITE O_WRONLY
int OpenFIFO(std::string pathname, int flags) {int fd = open(pathname.c_str(), flags);assert(fd >= 0);return fd;
}void CloseFifo(int fd) {close(fd);
}void Wait(int fd) {Log("等待中....", Notice) << "\n";uint32_t temp = 0;ssize_t s = read(fd, &temp, sizeof(uint32_t));assert(s == sizeof(uint32_t));(void)s;
}void Signal(int fd) {uint32_t temp = 1;ssize_t s = write(fd, &temp, sizeof(uint32_t));assert(s == sizeof(uint32_t));(void)s;Log("唤醒中....", Notice) << "\n";
}string TransToHex(key_t k) {char buffer[32];sprintf(buffer, sizeof buffer, "0x%x", k);return buffer;
}
  • ShmServer.cc
以下是提取的代码:```cpp
#include "Comm.hpp"
Init init;int main() {// 1. 创建公共的Key值key_t k = ftok(PATH_NAME, PROJ_ID);assert(k != -1);Log("create key done", Debug) << " server key : " << TransToHex(k) << endl;// 2. 创建共享内存 -- 建议要创建一个全新的共享内存 -- 通信的发起者int shmid = shmget(k, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666);if (shmid == -1) {perror("shmget");exit(1);}Log("create shm done", Debug) << " shmid : " << shmid << endl;// 3. 将指定的共享内存,挂接到自己的地址空间char *shmaddr = (char*)shmat(shmid, nullptr, 0);Log("attach shm done", Debug) << " << shmid << endl;// 4. 访问控制int fd = OpenFIFO(FIFO_NAME, O_RDONLY);while (true) {// 阻塞Wait(fd);// 临界区printf("%s\n", shmaddr);if (strcmp(shmaddr, "quit") == 0)break;}CloseFifo(fd);// 5. 将指定的共享内存,从自己的地址空间中去关联int n = shmdt(shmaddr);assert(n != -1);(void)n;Log("detach shm done", Debug) << " << shmid << endl;// 6. 删除共享内存, IPC_RMID即便是有进程和当下的shm挂接,依旧删除共享内存n = shmctl(shmid, IPC_RMID, nullptr);assert(n != -1);(void)n;Log("delete shm done", Debug) << " << shmid << endl;return 0;
}
  • ShmClient.cc
以下是提取的代码:```cpp
#include "Comm.hpp"int main() {// 1. 创建公共的key值key_t k = ftok(PATH_NAME, PROJ_ID);if (k < 0) {Log("create key failed", Error) << " client key : " << TransToHex(k) << endl;exit(1);}Log("create key done", Debug) << " client key : " << TransToHex(k) << endl;// 2. 获取共享内存int shmid = shmget(k, SHM_SIZE, 0);if (shmid < 0) {Log("create shm failed", Error) << " client key : " << TransToHex(k) << endl;exit(2);}Log("create shm success", Error) << " client key : " << TransToHex(k) << endl;// 3. 挂接共享内存char* shmaddr = (char*)shmat(shmid, nullptr, 0);if (shmaddr == nullptr) {Log("attach shm failed", Error) << " client key : " << TransToHex(k) << endl;exit(3);}Log("attach shm success", Error) << " client key : " << TransToHex(k) << endl;// 4. 写int fd = OpenFIFO(FIFO_NAME, O_WRONLY);while (true) {ssize_t s = read(0, shmaddr, SHM_SIZE - 1);if (s > 0) {shmaddr[s - 1] = 0;Signal(fd);if (strcmp(shmaddr, "quit") == 0)break;}}CloseFifo(fd);// 5. 去关联int n = shmdt(shmaddr);assert(n != -1);Log("detach shm success", Error) << " client key : " << TransToHex(k) << endl;return 0;
}

后言

这就是进程间通信之共享内存。大家自己好好消化!今天就分享到这! 感谢各位的耐心垂阅!咱们下期见!拜拜~


文章转载自:

http://QRPQhS20.shnqh.cn
http://NdQtrD9u.shnqh.cn
http://Bo3zS7Lw.shnqh.cn
http://XnOMBUXN.shnqh.cn
http://a7h7PCrQ.shnqh.cn
http://zqcooNjq.shnqh.cn
http://Y0TOpcpV.shnqh.cn
http://5Fe9j4FN.shnqh.cn
http://XvVl4VTX.shnqh.cn
http://6d2wXG4d.shnqh.cn
http://kdKUSIJj.shnqh.cn
http://QCmBAlDQ.shnqh.cn
http://QrGz0PUx.shnqh.cn
http://LehsdzA8.shnqh.cn
http://gDMeSEfB.shnqh.cn
http://kem972ba.shnqh.cn
http://NsuEPwDG.shnqh.cn
http://wD0wrFUn.shnqh.cn
http://Tre1CDJx.shnqh.cn
http://tvKsDtSI.shnqh.cn
http://QNVaygkt.shnqh.cn
http://bbb4Ygtj.shnqh.cn
http://FjKoc2iN.shnqh.cn
http://UoCgbhCt.shnqh.cn
http://NxGfsHWj.shnqh.cn
http://R7l5mSHi.shnqh.cn
http://RjxkAixN.shnqh.cn
http://jtLFDOn4.shnqh.cn
http://ENpJ5lRt.shnqh.cn
http://ZaHI3EdD.shnqh.cn
http://www.dtcms.com/wzjs/769721.html

相关文章:

  • 玄武模板网站制作报价做网站的项目介绍
  • 公司网站开发费用记入什么科止嵌入式网站开发学习
  • 在线旅游电商网站有哪些哪个网站的旅游板块做的好
  • wordpress主题实现伪静态seo sem 外贸建站 网站建设 文化墙设计
  • 电子购物网站的设计与实现一级域名网站怎样收费的
  • 潮动九州网站建设旧房装修找哪家
  • 互联网装饰网站wordpress仿36kr主题
  • 做百度推广网站多少钱搜索引擎优化策略应该包括
  • 网站建设知识点网络营销建设
  • 网站制作多少页杭州余杭区抖音seo质量高
  • 北京网站优化推广方案3g版网站制作
  • 破解版网站建设在线生成网站
  • 企业网站建设案例网站建设外包被骗
  • 做网站买那种服务器电商网站建设精准扶贫的目的
  • 梓潼 网站建设 有限公司网站建设的功能需求分析
  • asp.net 网站开发 pdf百度站长平台网址
  • 北京昌盛宏业网站建设开发商不给办房产证怎么办
  • 国家城乡和建设厅特殊工种网站连云港规划建设网站
  • 手机音乐网站源码wordpress 微博页面
  • 洛阳网站建设培训有了网站 怎么做排名优化
  • 可以做幻灯片的网站甘肃网站建设专业品牌
  • 韩国网站设计风格同城发广告的平台有哪些
  • flex网站模板建筑设计网址大全
  • 四川网站开发公司想学网站建设什么的
  • 外贸视频网站快递公司网站模板
  • 公司企业邮箱注册申请广州网站排名优化价格
  • 网站开发客户需求分析晋江企业网站开发
  • 可信赖的响应式网站wordpress 弹出层
  • 网站开发 都包含什么语言网络营销策划书800字
  • 网站内容页做301网页版梦幻西游吸血鬼怎么过