Linux共享内存编程实例
rust shared_memory 案例
![rust shared_memory 案例](https://img.taocdn.com/s3/m/60183942e97101f69e3143323968011ca300f7f2.png)
rust shared_memory 案例Rust是一种系统级语言,支持并发编程。
其中一个强大的功能是共享内存,让多个线程可以在同一块内存区域上同时进行读写操作。
对于并发编程来说,共享内存是一种高效的数据交换方式。
在本文中,我们将探讨Rust中的共享内存案例。
Rust提供了两种主要的共享内存机制:`Arc`和`Mutex`。
Arc表示Atomically Reference Counted(原子引用计数),它允许多个线程安全地共享同一个对象。
Mutex代表Mutual Exclusion(互斥),它确保在任何给定时间只能有一个线程访问共享资源。
我们将通过一个简单的案例来演示Rust中的共享内存的使用。
假设我们有一个任务,需要计算一个数组中所有元素的总和。
我们将使用多个线程并行地计算数组的不同区域,然后将每个线程的结果相加以得到最终的总和。
首先,我们需要引入Rust的标准库中的相关模块:```rustuse std::thread;use std::sync::{Arc, Mutex};```然后,我们定义一个计算线程的函数:```rustfn calculate_sum(data: Arc<Vec<i32>>, start: usize, end: usize, result: Arc<Mutex<i32>>) {let mut sum = 0;for i in start..end {sum += data[i];}let mut result = result.lock().unwrap();*result += sum;}```在上面的代码中,我们使用了`Arc<T>`来共享数组和结果变量,以及`Mutex<T>`来确保对结果变量的线程安全访问。
在每个线程中,我们使用start和end参数指定需要计算的数组区域。
接下来,我们创建主函数来调度多个计算线程:```rustfn main() {let data = Arc::new(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);let result = Arc::new(Mutex::new(0));let num_threads = 4;let chunk_size = data.len() / num_threads;let mut handles = Vec::new();for i in 0..num_threads {let start = i * chunk_size;let end = if i == num_threads - 1 {data.len()} else {(i + 1) * chunk_size};let data_clone = Arc::clone(&data);let result_clone = Arc::clone(&result);let handle = thread::spawn(move || {calculate_sum(data_clone, start, end, result_clone); });handles.push(handle);}for handle in handles {handle.join().unwrap();}let total_sum = *result.lock().unwrap();println!("Total sum: {}", total_sum);}```在上面的主函数中,我们首先创建一个包含数字1到10的vector,并使用`Arc::new`将其包装为一个在多个线程间安全共享的`Arc<Vec<i32>>`。
linux下共享内存
![linux下共享内存](https://img.taocdn.com/s3/m/162d9d353968011ca3009121.png)
Linux下共享内存SUNNY.MAN共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间) 从而使得这些进程可以相互通信,进程退出时会自动和已经挂接的共享内存区段分离,但是仍建议当进程不再使用共享区段时调用shmdt来卸载区段。
注意,当一个进程分支出父进程和子进程时,父进程先前创建的所有共享内存区段都会被子进程继承。
如果区段已经做了删除标记(在前面以IPC_RMID指令调用shmctl),而当前挂接数已经变为0,这个区段就会被移除。
Linux中通过API函数shmget创建的共享内存一般都是在程序中使用shmctl来释放的,但是有时为了调试程序,开发人员可能通过Ctrl + C等方式发送中断信号来结束程序,此时程序申请的共享内存就不能得到释放,当然如果程序没有改动的话,重新运行程序时仍然会使用上次申请的共享内存,但是如果我们修改了程序,由于共享内存的大小不一致等原因会导致程序申请共享内存错误。
因此,我们总是希望每次结束时就能释放掉申请的共享内存。
有两种方法可以用来释放共享内存:第一种:如果总是通过Crtl+C来结束的话,可以做一个信号处理器,当接收到这个信号的时候,先释放共享内存,然后退出程序。
第二种:不管你以什么方式结束程序,如果共享内存还是得不到释放,那么可以通过linux命令ipcrm shm shmid来释放,在使用该命令之前可以通过ipcs -m命令来查看共享内存。
共享内存查看使用ipcs命令,不加如何参数时,会把共享内存、信号量、消息队列的信息都打印出来,如果只想显示共享内存信息,使用如下命令:[root@localhost ~]# ipcs –m同样共享内存的大小也可以用ipcs –lm来查看它的上限下限。
shmget( ) 创建一个新的共享内存区段取得一个共享内存区段的描述符shmctl( ) 取得一个共享内存区段的信息为一个共享内存区段设置特定的信息移除一个共享内存区段shmat( ) 挂接一个共享内存区段shmdt( ) 于一个共享内存区段的分离同样共享内存的大小也可以用ipcs –lm来查看它的上限下限。
实验8Linux的内存管理
![实验8Linux的内存管理](https://img.taocdn.com/s3/m/6baca31bac02de80d4d8d15abe23482fb5da0260.png)
内存管理的概念
内存管理的定义
内存管理是指操作系统对计算机内存 资源的分配、回收、保护和扩充等一 系列操作,以确保系统高效、稳定地 运行。
内存管理的目标
提高内存利用率,减少内存碎片,实 现多任务环境下的内存共享和保护, 以及提供虚拟内存等。
Linux内存管理的特点
分段和分页机制
Linux采用分段和分页机制来管理内存,将物理内 存划分为大小相等的页框,同时将进程地址空间 划分为多个段,每个段对应一个页表项,实现地 址空间的隔离和权限控制。
。
03 通过实验操作和观察,加深对Linux内存管理的 理解和认识。
实验环境
操作系统
Linux(建议使用Ubuntu或CentOS等常见发行版 )
开发工具
GCC编译器、GDB调试器、Valgrind内存检测工 具等。
实验材料
一台配置有Linux操作系统的计算机,具备基本的 编程和调试能力。
02
Linux内存管理概述
VS
共享内存的实现方式
在Linux中,共享内存可以通过shmget() 、shmat()和shmdt()等系统调用来实现 。首先,使用shmget()函数创建一个共 享内存段;然后,使用shmat()函数将共 享内存段连接到当前进程的地址空间;最 后,使用shmdt()函数将共享内存段从当 前进程的地址空间中分离。
06
内存优化与性能提升
内存泄漏问题及其解决方案
内存泄漏定义
内存泄漏是指程序在申请内存后,未能正确释放,导致系统内存逐 渐耗尽的现象。
检测工具
使用Valgrind等内存检测工具,可以检测程序中的内存泄漏问题。
解决方案
及时释放不再使用的内存,避免不必要的内存申请,采用智能指针等 RAII技术来管理内存。
《Linux高级系统编程》教学教案
![《Linux高级系统编程》教学教案](https://img.taocdn.com/s3/m/52759f9b88eb172ded630b1c59eef8c75fbf95ed.png)
《Linux高级系统编程》教学教案一、教学目标1. 让学生掌握Linux系统编程的基本概念和原理。
2. 培养学生熟练使用Linux系统编程API的能力。
3. 使学生了解Linux系统编程的高级主题和技巧。
4. 培养学生解决实际问题的能力,提高他们在Linux环境下的软件开发水平。
二、教学内容1. Linux系统编程概述讲解Linux系统编程的基本概念、特点和优势。
2. 文件I/O操作介绍Linux文件I/O模型,讲解文件的打开、关闭、读写、同步等操作。
3. 进程管理讲解Linux进程的概念、创建、终止、进程间通信等知识。
4. 线程管理介绍Linux线程的基本概念、创建、同步、互斥等知识。
5. 高级I/O操作讲解Linux高级I/O操作,如异步I/O、直接I/O、内存映射I/O等。
三、教学方法1. 讲授法:讲解基本概念、原理和知识点。
2. 案例教学法:通过实际案例让学生掌握编程技巧和方法。
3. 实验教学法:安排实验课程,让学生亲自动手实践,提高实际操作能力。
四、教学环境1. 教室环境:投影仪、计算机、网络等。
2. 实验环境:装有Linux操作系统的计算机、网络等。
五、教学评估1. 课堂问答:检查学生对课堂知识的理解和掌握程度。
2. 实验报告:评估学生在实验过程中的动手能力和解决问题能力。
3. 课程作业:检查学生对课程知识点的综合运用能力。
4. 期末考试:全面评估学生对本门课程的掌握程度。
六、信号处理1. 信号基本概念讲解信号的定义、作用和信号处理的基本方法。
2. 信号处理函数介绍Linux信号处理函数,如signal(), rse(), sigaction()等。
3. 信号在进程和线程中的处理讲解信号在进程和线程中的传播和处理机制。
七、同步与互斥1. 同步与互斥基本概念讲解同步与互斥的概念、作用和应用场景。
2. 互斥锁介绍Linux互斥锁的使用,如pthread_mutex_lock(), pthread_mutex_unlock()等。
linux申请numa内存方法
![linux申请numa内存方法](https://img.taocdn.com/s3/m/b0582e34a517866fb84ae45c3b3567ec102ddce7.png)
linux申请numa内存方法NUMA(Non-Uniform Memory Access)是一种用来处理多处理器系统中内存访问分布不均的技术。
NUMA架构中,每个处理器都有其私有的本地内存,同时也连接到共享内存中。
这种架构的目的是使每个处理器访问其本地内存的速度更快,并在需要时与其他处理器共享内存。
在Linux操作系统中,NUMA架构的支持是通过内核模块进行实现的。
在有NUMA架构的情况下,内核会自动将系统中的内存划分为多个节点。
每个节点都有其本地内存和共享内存,而各个节点之间的内存访问延迟是不同的。
如果应用程序能够使用NUMA感知的方式进行内存分配,则可以使程序更高效地利用系统的资源。
在Linux系统中,可以使用numactl命令来管理NUMA内存。
该命令可以在不同的NUMA节点之间分配内存。
以下是在Linux系统上申请NUMA内存的步骤:1. 检查系统是否支持NUMA在终端中输入以下命令:numactl hardware若系统支持NUMA,则会输出类似以下的信息:available: 2 nodes (0-1)node 0 cpus: 0 1 2 3node 0 size: 19027 MBnode 0 free: 14982 MBnode 1 cpus: 4 5 6 7node 1 size: 20480 MBnode 1 free: 19334 MBnode distances:node 0 10: 10 201: 20 102. 安装NUMA工具包如果系统未安装NUMA工具包,可以在终端中输入以下命令进行安装:sudo apt-get install numactl3. 申请NUMA内存在终端中输入以下命令:numactl membind=0 interleave=all <command>其中,membind参数表示内存绑定,0表示绑定到第一个节点上;interleave 参数表示交错内存分配,all表示将内存分配到所有节点上;<command>表示需要运行的命令或程序。
共享内存函数(shmget、shmat、shmdt、shmctl)及其范例 - guoping16的专栏 - 博客频道 - CSDN
![共享内存函数(shmget、shmat、shmdt、shmctl)及其范例 - guoping16的专栏 - 博客频道 - CSDN](https://img.taocdn.com/s3/m/f27a9b6af5335a8102d22064.png)
IPC_CREAT :当shmflg&IPC_CREAT 为真时,如果内核中不存在键值与 信号的发送和捕捉函数(alarm (1719) 、kill、raise、pause、 sleep、 abort) key 相等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返 进程的堆栈空间 (1247) 回此共享内存的标识符
/guoping16/article/details/6584058
1/10
2014年4月2日
评论排行
共享内存函数(shmget、shmat、shmdt、shmctl)及其范例 - guoping16的专栏 - 博客频道 -
函数 成功:返回共享内存的标识符 返回 消息队列函数(msgget、msgctl (4) 、msgsnd、 msgrcv)及其范例 值 出错:-1,错误原因存于error中
分类: Linux进程间通信 struct 目录(?) guoping16 null cmd gcc [+] linux 编程 2011-07-04 17:38 13141人阅读 评论(0) 收藏 举报
访问: 52118次 积分: 946分 排名: 第15089名 原创: 48篇 译文: 0篇 转载: 2篇 评论: 12条
最新评论 消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例 daemon_msg: 很有帮助!谢谢 消息队列函数(msgget、msgctl、msgsnd、msgrcv)及其范例 mysee1989: 挺详细的。谢谢 进程的堆栈空间 wangpeng2011314: 那么 windows 下的原理一致吗 ??? 会话、进程组与僵死进程 guoping16: 1.当登录终端时,就 产生一个会话,也就产生了一个 可操作的界面。2.proc3 | proc4 | p... 会话、进程组与僵死进程 mmwren: 你好,有个问题请教 一下,当登录终端时,shell进程 为首进程,也是前台进程吗?在 执行命令 proc3... System V 进程间通讯(IPC、ftok) luguangxu68: 很不错啊! 谢谢 了 字符串和内存操作函数 asdk77: 总结的真好!收下了! 标准I/O文件编程 luguangxu68: 嗨,哥们,你很 棒!!!加油
linux openmp 例子程序
![linux openmp 例子程序](https://img.taocdn.com/s3/m/be92e9f96037ee06eff9aef8941ea76e58fa4a8d.png)
linux openmp 例子程序标题:Linux OpenMP例子程序1. OpenMP简介OpenMP是一种并行编程模型,可以在共享内存系统上实现并行计算。
它使用指令集和编译器指示来将串行代码转换为并行代码,从而实现更高效的计算。
2. Hello World程序下面是一个简单的OpenMP程序,用于打印“Hello World”:```c#include <stdio.h>#include <omp.h>int main() {#pragma omp parallel{int thread_id = omp_get_thread_num();printf("Hello World from thread %d\n", thread_id);}return 0;}```该程序使用了`#pragma omp parallel`指令来创建线程,并使用`omp_get_thread_num()`函数获取线程ID。
3. 并行for循环OpenMP可以很方便地并行化for循环。
下面是一个计算数组元素和的例子:```c#include <stdio.h>#include <omp.h>int main() {int sum = 0;#pragma omp parallel for reduction(+:sum)for (int i = 0; i < 100; i++) {sum += i;}printf("Sum: %d\n", sum);return 0;}```在上述代码中,`#pragma omp parallel for`指令将for循环并行化,`reduction(+:sum)`指示OpenMP将每个线程的局部和累加到全局和`sum`中。
4. 并行化矩阵乘法OpenMP也可以用于并行化矩阵乘法。
下面是一个简单的矩阵乘法示例:```c#include <stdio.h>#include <omp.h>#define N 100void matrix_multiply(int A[N][N], int B[N][N], int C[N][N]) {#pragma omp parallel forfor (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {C[i][j] = 0;for (int k = 0; k < N; k++) {C[i][j] += A[i][k] * B[k][j];}}}}int main() {int A[N][N];int B[N][N];int C[N][N];// 初始化A和B矩阵matrix_multiply(A, B, C);// 打印结果return 0;}```在上述代码中,`#pragma omp parallel for`指令将外层循环并行化,从而加快矩阵乘法的计算速度。
在linux下实现读者写者问题源代码
![在linux下实现读者写者问题源代码](https://img.taocdn.com/s3/m/d79d864d78563c1ec5da50e2524de518964bd33c.png)
在linux下实现读者写者问题源代码读者写者问题是计算机科学中的一个经典同步问题,用于描述多个读者和写者对共享资源的访问。
在这个问题中,多个读者可以同时读取共享资源,但是写者在写入共享资源时必须独占访问。
在Linux下,我们可以使用线程和互斥锁来实现读者写者问题。
下面是一个简单的源代码示例:```c#include <stdio.h>#include <stdlib.h>#include <pthread.h>#define READERS_COUNT 5#define WRITERS_COUNT 2pthread_mutex_t mutex;pthread_cond_t cond_reader, cond_writer;int readers = 0;int writers = 0;void *reader(void *arg) {int id = *(int *)arg;while (1) {pthread_mutex_lock(&mutex);while (writers > 0) {pthread_cond_wait(&cond_reader, &mutex); }readers++;pthread_mutex_unlock(&mutex);// 读取共享资源printf("Reader %d is reading\n", id);pthread_mutex_lock(&mutex);readers--;if (readers == 0) {pthread_cond_signal(&cond_writer);}pthread_mutex_unlock(&mutex);}pthread_exit(NULL);}void *writer(void *arg) {int id = *(int *)arg;while (1) {pthread_mutex_lock(&mutex);while (readers > 0 || writers > 0) {pthread_cond_wait(&cond_writer, &mutex); }writers++;pthread_mutex_unlock(&mutex);// 写入共享资源printf("Writer %d is writing\n", id);pthread_mutex_lock(&mutex);writers--;pthread_cond_signal(&cond_writer);pthread_cond_broadcast(&cond_reader);pthread_mutex_unlock(&mutex);}pthread_exit(NULL);}int main() {pthread_t readers[READERS_COUNT];pthread_t writers[WRITERS_COUNT];int reader_ids[READERS_COUNT];int writer_ids[WRITERS_COUNT];pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond_reader, NULL);pthread_cond_init(&cond_writer, NULL);// 创建读者线程for (int i = 0; i < READERS_COUNT; i++) {reader_ids[i] = i + 1;pthread_create(&readers[i], NULL, reader, &reader_ids[i]); }// 创建写者线程for (int i = 0; i < WRITERS_COUNT; i++) {writer_ids[i] = i + 1;pthread_create(&writers[i], NULL, writer, &writer_ids[i]); }// 等待线程结束for (int i = 0; i < READERS_COUNT; i++) {pthread_join(readers[i], NULL);}for (int i = 0; i < WRITERS_COUNT; i++) {pthread_join(writers[i], NULL);}pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond_reader);pthread_cond_destroy(&cond_writer);return 0;}```在这个源代码中,我们使用了互斥锁(`pthread_mutex_t`)和条件变量(`pthread_cond_t`)来实现读者写者问题的同步。
操作系统实验---进程通信——共享存储区和信号量
![操作系统实验---进程通信——共享存储区和信号量](https://img.taocdn.com/s3/m/d2a1d8a5aeaad1f346933fb8.png)
实验报告实验题目姓名:学号:课程名称:操作系统实验所在学院:信息科学与工程学院专业班级:计算机任课教师:实验项目名称进程通信——共享存储区和信号量一、实验目的与要求:1、了解和熟悉共享存储机制2、了解和熟悉信号量机制3、熟悉信号量机制中使用的数据结构和信号量机制的操作以及控制。
4、了解共享主存段机制,学会对共享主存段的系统调用。
二、实验设备及软件:1、PC机一台2、Linux操作系统三、实验方法(原理、流程图)一、共享存储区1、共享存储区机制的概念共享存储区(Share Memory)是 UNIX 系统中通信速度最高的一种通信机制。
该机制可使若干进程共享主存中的某一个区域,且使该区域出现(映射)在多个进程的虚地址空间中。
另一方面,一个进程的虚地址空间中又可连接多个共享存储区,每个共享存储区都有自己的名字。
当进程间欲利用共享存储区进行通信时,必须先在主存中建立一共享存储区,然后将它附接到自己的虚地址空间上。
此后,进程对该区的访问操作,与对其虚地址空间的其它部分的操作完全相同。
进程之间便可通过对共享存储区中数据的读、写来进行直接通信。
图示列出二个进程通过共享一个共享存储区来进行通信的例子。
其中,进程 A 将建立的共享存储区附接到自己的 AA’区域,进程 B 将它附接到自己的 BB’区域。
应当指出,共享存储区机制只为进程提供了用于实现通信的共享存储区和对共享存储区进行操作的手段,然而并未提供对该区进行互斥访问及进程同步的措施。
因而当用户需要使用该机制时,必须自己设置同步和互斥措施才能保证实现正确的通信。
二、涉及的系统调用1、shmget( )创建、获得一个共享存储区。
系统调用格式: shmid=shmget(key,size,flag)参数定义: int shmget(key,size,flag);key_t key;int size,flag;其中,key是共享存储区的名字;size是其大小(以字节计);flag是用户设置的标志,如IPC_CREAT。
vfork +exec 例子
![vfork +exec 例子](https://img.taocdn.com/s3/m/f81c3381ab00b52acfc789eb172ded630a1c984b.png)
vfork + exec 是一个在 Linux 操作系统中常用的技术组合,它的作用是创建一个新的进程,然后用另一个程序替换它。
在本文中,我们将介绍这一技术的原理、用法和一个具体的例子。
一、vfork 和 exec 的原理1. vfork 是一个系统调用,它用于创建一个新的进程,但是它与 fork 不同的是,vfork 并不会复制父进程的位置区域空间,而是直接共享父进程的位置区域空间。
2. exec 也是一个系统调用,它用于加载一个新的程序到当前的进程空间中,并开始执行这个新的程序。
exec 系统调用会把当前进程的位置区域空间替换为新程序的位置区域空间,并开始执行新程序的代码。
二、vfork 和 exec 的用法1. 使用 vfork 和 exec 的一般步骤如下:1) 父进程调用 vfork,创建一个新的子进程。
2) 子进程调用 exec,加载一个新的程序到当前的进程空间中。
2. vfork 和 exec 的组合可以用于在一个进程中执行另一个程序,而不需要创建一个新的进程。
这在一些特定的场景下非常有用,比如在某个进程中执行系统命令、启动一个新的服务等。
三、vfork + exec 的例子下面我们来看一个具体的例子,来演示如何使用 vfork 和 exec 来执行一个新程序。
我们假设有一个程序 m本人n.c,它的代码如下所示:```c#include <stdio.h>#include <unistd.h>int m本人n() {printf("This is the m本人n process\n");pid_t pid = vfork();if (pid < 0) {// vfork 出错perror("vfork");return -1;}else if (pid == 0) {// 子进程execl("/bin/ls", "ls", NULL);// 如果 execl 执行成功,下面的代码不会被执行到perror("execl");_exit(1);}printf("This is still the m本人n process\n");return 0;}```在这个例子中,我们首先在 m本人n 函数中调用 vfork 创建一个新的子进程,然后在子进程中调用 exec 加载 ls 程序,并执行它。
浅析Linux中的共享内存机制
![浅析Linux中的共享内存机制](https://img.taocdn.com/s3/m/364008b1fd0a79563c1e728b.png)
十计 算机 内 ;后者 则 囊破 了 限制 , 形 成 了 蔼
基于 套接 字 (o e 的进程 阀通 信 机制 。 5 c t k J k x刚把 两者都 缒 承 了下来 所谓 的 l 机 制是进 程 阆通信 P c tr r e g0 s e  ̄ ̄ cm i t n m n sf )的墒 写 它包括 T 息队列 . o u ̄  ̄ 消
维普资讯
中国科技信息 20 年第 1 期 06 5 C I CEC N E H A S I EA D T ̄ N N L G NO M TO u 2 0 O Y I R A I Ag 06 F N
浅析 L n x中的 iu 共享 内存机 制
共事 内存 和 信号量 。其 中其 享 内存 0h a rd e
mmr)是薮率 最高的 I 机 制,它允许 多个进 eo y P c 程共 享一 段特 球 内存 区域 中 的数船 , 可 以擘 读写 普通 内存 空 间一 样读 写共 享 内存 中 的靛 据 . 而不 需 通 过其 他任 何特 殊的 方式 簧 ssm V l . y e t 进程闸 通信 ; 享内存 共
Ps oi x消息队列 ,ss m V消息队列。有 yt e 进程 对象 对于共 事内存 的访问通 过 足够投限的进 程可以向队列 中添加 消息. ke ( )来控制 ,同时通过 k Y进行 Y 键 e 波赋予读权限的进程则 可以读走队列中的 访问权 限的检查 。 由于同 一块 共享 内存 消启、 。消扈. 列克服 了信 号承载信 息量 可以以 i种不 同的形式 } 现 ,比如 在虚 队 H 少 ,管 道只能 承载 无格式字节 流以 及缓 拟内存中是通过 v a e — t uc > m— a s t r r 冲区大 小受限等 缺点 。 v  ̄ e >f d nty一 m_ e r >d io e >L n qd 』 进行 4. ) 信号 ( n l :信 譬是比较复 标 识 、在虚拟 内存文件 中通过 f l > Sg a 】 J Ie 杂的通 信方式 , 用于 通知 接受进程 有某 fde r >d io e > n 进行标识 、 nt y n d 一 1io 而 种事 件发 生 ,除 r 于进 程 间通信 外 . 在共享 内存 中则通过 src p d 用 tu t[ i 进行标 c 进程还可以发送信号给进程本身 ・L n x i u 阻 但 币论是 何种标识 形式 .本 质上他 除了支持 Un x早期信号语 殳函数 sga 们拥有 一个唯 一的共同标识 .就是 k i i l eY 外 .还主持语 义符合 P sx. 标准的信号 值 o ̄ i 函数 sg c i n ( ia t o 实际 j.法函数是基于 二 任何 L 叫x进程创建之初,都有很大 i B SD的 .BSD 为了实现 可靠信号机制 , 的虚拟 地址空 间 ,这块 虚拟 地址空 间只 又能够统一对外接 口,用sg c in函数 有一 部 分 存放 代 码 、 数据 、堆栈 等 信 i a to 重新实现 了s g a i n I函数) 息 ,其余都是 摩闲的 。 当共享内 存被连 5. ) 信号量 (e a o e :主要作 接(ta h 后 ,就被映射 入空阑的虚拟地 s r ph r ) e atc ) 为进程间以及同一进程 内不同线程之 间的 址空 间,随后 进程就 可以像读 写普通 同 步手 段 。 内存 区域 一样 来处 理 该段 共享 内存 了。 6. ) 共辜 内存:使得多个进程 可以访 同时 内存共享 之后 ,就不 再检查进 程是 问同一块内存空 间,是最快的可用 I C形 如何来 使用这 块内存 的 ,比如我们 可以 P 式 。是 针对其 他通信 机制 运行效率 较低 采用信号量机 制来解决 内存访问的同步问 而设 计的。 往往与其 它通 信机制 ,如信 题 等 。 号量 结合使 用 .来达 到进 程间的 同步及 s se [ C机制下创建 与使用共 y tn V P r 斥。 享内存通过 4个 APl 来完成 ,分 别是 : 1原理及实现 s m e( h g t)创建一块 共享内存l s se PC机制下的共 享内存本 y tm V I s ma ( 一块已存在的共 享内存映 h t)将 质是 一段特殊 的内存 区域 ,进程 间需 要 射到一 个进程 的地址空 间 s md ( h t)取消一个进程的地址空闻到 共 享的数 据 被放 在该 共享 内 存区域 中 , 所有需要访问该共享区城的进程都要把 该 块共 卓内存 块的映射 ; s hmc l)管理 共享内存.用于执行 t( 共享I 映射到本进程的地址空 间中去。 夏域 选样一个使用共享内存的进程可以将信息 对共享 内存的各种 控制命令 与操 作。 写 入凌空间 ,而 另一 个使 用共享 内存的 r面我 们通过 一个简单的示例程序 来 进程叉可以通过简单的内存读 操作获取刚 进一 步 了解 系统 调用 幽数 的使 用方 法。 才 写入的信 息 .使得两 个不 同进 程之 间 在 这 个示 例 程 序 巾 ,主 要完 成 以 下功 进 行了一次 信息 交换 ,从而实现 进程 间 能 : 先调用 s mg  ̄ h e( )创建 一 12 个 块 04 的通 信。共 享内 存允许一 个或 多个进程 字节的 享内存同时返回创建的共享内存 通过同时出现往它们的虚拟地址空 间的内 标 识符 ・然 后 f 一个 }进 程 ,调 用 r ok 存进 行通信 ,而 这块虚拟 内存 的页丽被 s ma0 h L  ̄数将该共享内存连接到 自己的虚
(最终版)linux下python和c++相互调用共享内存通信
![(最终版)linux下python和c++相互调用共享内存通信](https://img.taocdn.com/s3/m/a363c351bf1e650e52ea551810a6f524ccbfcb22.png)
(最终版)linux下python和c++相互调⽤共享内存通信本⽂主要⽤于python和c++相互通信,通过共享内存相互传递数据,图像,数组,结构体。
python优势在于开发快速⽅便,有很多扩展库可⽤,且深度学习很多都是python写的。
c++底层速度快,但是开发慢,尤其是很多SLAM和图像处理的只有c++版本。
为了调试开发⽅便,有时候需要嫁接两个⼯程,根据⾃⼰实际需要决定。
⼤概思路1 c++编译动态库完成各种共享内存的实际操作。
2 python端调⽤c++动态库进⾏共享内存数据交互。
3 c++端调⽤c++动态库进⾏共享内存数据交互。
主要⽤的的是ctypes资料共享内存在 Linux 实现内存共享的函数主要有 shmget、shmat、shmdt、shmctl 这么四个。
1、shmget 得到或者创建⼀个共享内存对象int shmget(key_t key, size_t size, int shmflg)其中 key_t key 的值为⼀个IPC键值,可以通过IPC_PRIVATE 建⽴⼀个新的键值为0的共享对象,但这并不能保证与IPC对象的对应关系,不同进程之间需要同⼀个且不会重复的IPC键值来完成通信,⼀般此参数使⽤ftok函数来进⾏创建IPC键值。
size_t size 是映射共享内存的⼤⼩,单位为字节 (Byte),但在创建时这⾥的最⼩分配单位是⼀页,⼤致为4KB,当你超过4KB但是⼩于8KB时会主动分配两页,也就是不⾜⼀页(4KB)的按照⼀页计算。
int shmflg 参数是需要注明的操作模式。
0:取键值对应的共享内存,若此键值相应的共享内存不存在就报错。
IPC_CREAT:存在与键值对应的共享内存则返回标识符,若不存在则创建共享内存返回标识符。
IPC_CREAT|IPC_EXCL:不存在相应键值的共享内存则创建此共享内存,若存在则报错返回值:成功返回共享内存的标识符,失败返回-1。
linux进程间通信实验心得
![linux进程间通信实验心得](https://img.taocdn.com/s3/m/7279ea9577eeaeaad1f34693daef5ef7ba0d129b.png)
linux进程间通信实验心得随着对Linux系统的深入了解,我对进程间通信(IPC)的重要性有了更深刻的认识。
在这次实验中,我通过实际操作,掌握了多种Linux进程间通信的方法,并对它们的特点和应用场景有了更清晰的了解。
实验过程中,我主要接触了三种主要的进程间通信方法:管道(Pipe)、信号(Signal)和共享内存(Shared Memory)。
每种方法都有其独特的特点和使用场景。
管道是最基本的进程间通信方式,它允许父子进程之间进行通信。
通过管道,一个进程可以将数据写入到管道中,而另一个进程可以从管道中读取数据。
我在实验中创建了多个进程,并通过管道实现了它们之间的数据传递。
虽然管道简单易用,但它的通信能力有限,只能用于父子进程或兄弟进程之间的通信。
信号是一种异步的进程间通信方式,一个进程可以向另一个进程发送信号。
接收进程可以根据信号的类型采取不同的行动。
我在实验中通过信号实现了进程间的控制和同步。
虽然信号可以用于任何两个进程之间的通信,但由于它是异步的,使用起来需要小心处理信号的捕获和处理。
共享内存是一种高效的进程间通信方式,它允许多个进程访问同一块内存空间。
通过共享内存,进程可以快速地读写数据,避免了数据在进程间传递的开销。
我在实验中创建了多个进程,让它们共享一块内存区域,并通过读写共享内存实现了数据的快速传递。
共享内存的优点是通信速度快,但需要处理好同步和互斥问题,以避免数据冲突和错误。
通过这次实验,我对Linux进程间通信有了更深入的了解。
在实际应用中,需要根据具体的需求和场景选择合适的进程间通信方法。
同时,我也认识到进程间通信的复杂性和挑战性,需要仔细考虑和处理各种可能的问题。
在未来的学习和工作中,我将继续深入学习Linux系统及其相关技术,不断提高自己的技能和能力。
同时,我也将关注新技术的发展和应用,保持对行业的敏感度和竞争力。
linux 共享内存 参数设置
![linux 共享内存 参数设置](https://img.taocdn.com/s3/m/3c15d8dc534de518964bcf84b9d528ea80c72f5f.png)
linux 共享内存参数设置Linux共享内存是一种在多个进程之间共享数据的机制。
它允许多个进程访问同一块内存区域,从而实现高效的数据交换和通信。
在使用共享内存时,需要设置一些参数来确保其正常运行。
我们需要设置共享内存的大小。
共享内存的大小决定了可以存储的数据量。
在设置大小时,需要考虑到实际需求和系统资源的限制。
如果共享内存过小,可能会导致数据丢失或无法存储所需的数据;如果共享内存过大,可能会占用过多的系统资源。
因此,合理设置共享内存的大小非常重要。
我们需要设置共享内存的访问权限。
共享内存的访问权限可以控制哪些进程可以读取和写入共享内存。
通常,我们可以使用权限掩码来设置访问权限。
权限掩码是一个8位的二进制数,每一位代表一个权限,例如读、写、执行等。
通过设置权限掩码,可以精确地控制进程对共享内存的访问权限。
我们还可以设置共享内存的标志位。
标志位用于指定共享内存的一些额外属性,例如是否在创建时清空共享内存、是否允许多个进程同时访问共享内存等。
通过设置标志位,可以根据实际需求来调整共享内存的行为。
除了上述参数,还有一些其他参数也需要设置。
例如,我们需要设置共享内存的键值,用于唯一标识共享内存。
键值可以是一个整数或字符串,通常使用ftok()函数来生成。
此外,我们还需要设置共享内存的标识符,用于在代码中引用共享内存。
在使用共享内存时,我们需要注意一些常见的问题。
首先,由于共享内存是多个进程共享的,因此需要使用锁机制来保护共享内存的访问。
锁可以防止多个进程同时写入相同的数据,从而避免数据的不一致性。
其次,需要注意共享内存的生命周期管理。
在使用完共享内存后,需要及时释放它,以免造成资源的浪费。
最后,还需要注意共享内存的安全性。
由于多个进程可以访问共享内存,因此需要确保数据的安全性,避免数据被非法篡改。
总结一下,Linux共享内存是一种高效的进程间通信机制。
在使用共享内存时,需要设置一些参数来确保其正常运行。
linux 共享存储磁盘的用法
![linux 共享存储磁盘的用法](https://img.taocdn.com/s3/m/3460b5aaafaad1f34693daef5ef7ba0d4a736da9.png)
linux 共享存储磁盘的用法Linux共享存储磁盘的用法共享存储磁盘是一种用于在多个计算机之间共享文件和数据的设备。
在Linux操作系统中,有几种方法可以实现共享存储磁盘的使用。
本文将一步一步详细介绍Linux共享存储磁盘的用法。
第一步:准备共享存储磁盘首先,需要准备一块磁盘作为共享存储设备。
可以使用硬盘、SSD或者NAS(网络附加存储)设备作为共享存储磁盘。
确保磁盘已经正确连入Linux系统并正确挂载。
第二步:安装必要的软件在Linux系统上,需要安装一些必要的软件来实现共享存储磁盘的使用。
常用的软件包括Samba和NFS(Network File System)。
Samba软件包用于共享存储磁盘给Windows系统,而NFS软件包用于共享存储磁盘给Unix-like系统。
使用以下命令来安装Samba和NFS软件包:sudo apt-get install sambasudo apt-get install nfs-kernel-server第三步:配置Samba共享如果你想共享存储磁盘给Windows系统,需要进行Samba的相关配置。
首先,在终端中运行以下命令来编辑Samba的主配置文件:sudo nano /etc/samba/smb.conf在配置文件中,你需要指定要共享的目录和共享的名称。
在配置文件的底部,添加以下行:[shared]comment = Shared Storagepath = /path/to/shared/directoryread only = noguest ok = yes在上述配置中,将“/path/to/shared/directory”替换为你要共享的目录的实际路径。
保存并关闭配置文件。
接下来,重新启动Samba服务以使配置生效:sudo systemctl restart smbd第四步:配置NFS共享如果你想共享存储磁盘给Unix-like系统,需要进行NFS的相关配置。
Shell脚本编写的高级技巧使用共享内存和进程间通信
![Shell脚本编写的高级技巧使用共享内存和进程间通信](https://img.taocdn.com/s3/m/503d24849fc3d5bbfd0a79563c1ec5da50e2d62a.png)
Shell脚本编写的高级技巧使用共享内存和进程间通信共享内存和进程间通信是Shell脚本编写中非常重要的技巧和概念。
它们可以帮助我们实现进程之间的数据传递和通信。
本文将介绍使用共享内存和进程间通信的高级技巧,以及如何在Shell脚本中应用这些技巧。
一、共享内存1.1 什么是共享内存共享内存是一种用于进程间通信的机制,它允许不同的进程访问同一块内存区域。
通过共享内存,多个进程可以实现数据共享,从而提高程序的效率。
1.2 在Shell脚本中使用共享内存在Shell脚本中使用共享内存需要借助一些系统命令和工具,比如ipcs、ipcrm等。
下面是一个使用共享内存实现数据传递的例子:```shell#!/bin/bash# 创建共享内存shm_id=$(ipcs -m | grep "0x" | awk '{ print $2 }')if [ -z "$shm_id" ]; thenshm_id=$(ipcmk -M | awk '{ print $NF }')fi# 写入数据data="Hello, shared memory!"echo -n "$data" > /dev/shm/$shm_id# 读取数据data=$(cat /dev/shm/$shm_id)echo "Shared memory data: $data"# 删除共享内存ipcrm -M $shm_id```这个脚本首先用ipcs命令检查是否已存在共享内存,如果不存在则用ipcmk命令创建一块共享内存。
然后,它通过echo命令将数据写入共享内存,再通过cat命令读取共享内存中的数据。
最后,使用ipcrm 命令删除共享内存。
二、进程间通信2.1 什么是进程间通信进程间通信(Inter-Process Communication,简称IPC)是指不同进程之间进行数据交换和通信的机制。
Linux命令高级技巧使用ipcs和ipcrm管理共享内存和信号量
![Linux命令高级技巧使用ipcs和ipcrm管理共享内存和信号量](https://img.taocdn.com/s3/m/0b63817182c4bb4cf7ec4afe04a1b0717ed5b341.png)
Linux命令高级技巧使用ipcs和ipcrm管理共享内存和信号量Linux命令高级技巧:使用ipcs和ipcrm管理共享内存和信号量在Linux操作系统中,共享内存和信号量是进程间通信的重要手段。
使用ipcs和ipcrm命令可以对共享内存和信号量进行管理和操作。
本文将介绍如何使用ipcs和ipcrm命令来高效管理共享内存和信号量。
一、共享内存介绍及管理共享内存是进程之间共享数据的一种方式,提高了进程间数据交换的效率。
在Linux中,使用ipcs命令可以查看当前系统中存在的共享内存情况。
```bash$ ipcs -m```上述命令将列出所有共享内存的相关信息,包括共享内存的标识符、大小、进程ID等。
通过查看这些信息,我们可以了解当前系统的共享内存使用情况。
接下来,我们可以使用ipcrm命令来删除无用的共享内存。
```bash$ ipcrm -m <共享内存标识符>```上述命令将删除指定标识符的共享内存。
需要注意的是,只有创建该共享内存的进程或具有足够权限的用户才能删除共享内存。
二、信号量介绍及管理信号量是用来协调多个进程之间对共享资源的访问的一种机制。
在Linux中,使用ipcs命令可以查看当前系统中存在的信号量。
```bash$ ipcs -s```上述命令将列出所有信号量的相关信息,包括信号量的标识符、当前值、进程ID等。
通过查看这些信息,我们可以了解当前系统的信号量使用情况。
与共享内存类似,我们可以使用ipcrm命令来删除无用的信号量。
```bash$ ipcrm -s <信号量标识符>```上述命令将删除指定标识符的信号量。
同样需要注意的是,只有创建该信号量的进程或具有足够权限的用户才能删除信号量。
三、使用案例下面以一个实际的使用案例来说明如何使用ipcs和ipcrm命令进行共享内存和信号量的管理。
假设我们有两个进程A和B,需要使用共享内存和信号量进行数据交换和同步。
Linux下的多线程编程实例解析
![Linux下的多线程编程实例解析](https://img.taocdn.com/s3/m/a80a537749d7c1c708a1284ac850ad02de8007d1.png)
Linux下的多线程编程实例解析1 引⾔ 线程(thread)技术早在60年代就被提出,但真正应⽤多线程到操作系统中去,是在80年代中期,solaris是这⽅⾯的佼佼者。
传统的Unix也⽀持线程的概念,但是在⼀个进程(process)中只允许有⼀个线程,这样多线程就意味着多进程。
现在,多线程技术已经被许多操作系统所⽀持,包括Windows/NT,当然,也包括Linux。
为什么有了进程的概念后,还要再引⼊线程呢?使⽤多线程到底有哪些好处?什么的系统应该选⽤多线程?我们⾸先必须回答这些问题。
使⽤多线程的理由之⼀是和进程相⽐,它是⼀种⾮常"节俭"的多任务操作⽅式。
我们知道,在Linux系统下,启动⼀个新的进程必须分配给它独⽴的地址空间,建⽴众多的数据表来维护它的代码段、堆栈段和数据段,这是⼀种"昂贵"的多任务⼯作⽅式。
⽽运⾏于⼀个进程中的多个线程,它们彼此之间使⽤相同的地址空间,共享⼤部分数据,启动⼀个线程所花费的空间远远⼩于启动⼀个进程所花费的空间,⽽且,线程间彼此切换所需的时间也远远⼩于进程间切换所需要的时间。
据统计,总的说来,⼀个进程的开销⼤约是⼀个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较⼤的区别。
使⽤多线程的理由之⼆是线程间⽅便的通信机制。
对不同进程来说,它们具有独⽴的数据空间,要进⾏数据的传递只能通过通信的⽅式进⾏,这种⽅式不仅费时,⽽且很不⽅便。
线程则不然,由于同⼀进程下的线程之间共享数据空间,所以⼀个线程的数据可以直接为其它线程所⽤,这不仅快捷,⽽且⽅便。
当然,数据的共享也带来其他⼀些问题,有的变量不能同时被两个线程所修改,有的⼦程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地⽅。
除了以上所说的优点外,不和进程⽐较,多线程程序作为⼀种多任务、并发的⼯作⽅式,当然有以下的优点: 1) 提⾼应⽤程序响应。
两台linux之间实现共享文件夹挂载实例
![两台linux之间实现共享文件夹挂载实例](https://img.taocdn.com/s3/m/ffe239c2aa00b52acfc7ca36.png)
linux之间实现共享文件夹挂载实例:一、linux存储服务器(10.89.8.5 域名:),linux客户端服务器(10.89.0.3 域名:)a、存储服务器配置如下:1、[wds@ ~]#mkdir /mnt/mm2、[wds@ ~]#chmod 777 /mnt/mm3、[wds@ ~]#vi /etc/exports -------编辑/etc 目录下的共享目录配置文件exports,指定共享目录及权限等。
对NFS服务的访问是由exports来批准,它枚举了若干有权访问NFS服务器上文件系统的主机名。
在该文件里添加如下内容:/mnt/mm *(rw,) *表示所有的客户机都可以挂接此目录, rw表示挂接此目录的客户机对该目录有读写的权力,4、[wds@ ~]#service nfs restart ----开启nfs服务5、[wds@ ~]#service nfs status ----检查nfs服务是否开启6、[wds@ ~]#service portmap restart ----开启端口映射服务b、客户端服务器配置如下:1、[wds@ ~]#mkdir /home/jj2、[wds@ ~]#mount -t nfs 10.89.8.5:/mnt/mm /home/jj3、[wds@ ~]#df ---验证挂载目录是否成功二、[wds@localhost ~]# exportfs [-aruv] 参数:参数说明:-a: 全部挂载(或者卸载)/etc/exports 文件的设置-r: 从新挂载/etc/exports 里设置,此外,同步更新/etc/exports 及/var/lib/nfs/xtab 的内容-u: 卸载某一目录-v: 在导出时,将共享目录显示在屏幕上例如:[wds@localhost ~]# exportfs rv 全部从新导出一次[wds@localhost ~]# exportfs au 全部卸载掉三、Linux 服务器端NFS 服务器的配置以root 身份登陆Linux 服务器,编辑/etc 目录下的共享目录配置文件exports,指定共享目录及权限等。
linux简单的DMA例程
![linux简单的DMA例程](https://img.taocdn.com/s3/m/25eea63c42323968011ca300a6c30c225901f074.png)
linux简单的DMA例程⼀个简单的使⽤DMA 例⼦⽰例:下⾯是⼀个简单的使⽤DMA进⾏传输的驱动程序,它是⼀个假想的设备,只列出DMA相关的部分来说明驱动程序中如何使⽤DMA 的。
函数dad_transfer是设置DMA对内存buffer的传输操作函数,它使⽤流式映射将buffer的虚拟地址转换到物理地址,设置好DMA控制器,然后开始传输数据。
int dad_transfer(struct dad_dev *dev, int write, void *buffer, size_t count) { dma_addr_t bus_addr; unsigned long flags; /* Map the buffer for DMA */ dev->dma_dir = (write ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); dev->dma_size = count; //流式映射,将buffer的虚拟地址转化成物理地址 bus_addr = pci_map_single(dev->pci_dev, buffer, count, dev->dma_dir); dev->dma_addr = bus_addr; //DMA传送的buffer物理地址 //将操作控制写⼊到DMA控制器寄存器,从⽽建⽴起设备 writeb(dev->mand, DAD_CMD_DISABLEDMA); //设置传输⽅向--读还是写 writeb(dev->mand, write ? DAD_CMD_WR : DAD_CMD_RD); writel(dev->registers.addr, cpu_to_le32(bus_addr));//buffer物理地址 writel(dev->registers.len, cpu_to_le32(count)); //传输的字节数 //开始激活DMA进⾏数据传输操作 writeb(dev->mand, DAD_CMD_ENABLEDMA); return 0; }函数dad_interrupt是中断处理函数,当DMA传输完时,调⽤这个中断函数来取消buffer上的DMA映射,从⽽让内核程序可以访问这个buffer。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf( "shmat(
) failed/n" );
printf( "shared memory segment not found/n" ); return 0;
101. /*内存共享区段与旗语和消息队列不同,一个区段可以被锁定。 102. 103. 104. 105. 被锁定的区段不允许被交换出内存。这样做的优势在于,与其 把内存区段交换到文件系统,在某个应用程序调用时再交换回内存, 不如让它一直处于内存中,且对多个应用程序可见。从提升性能的角度 来看,很重要的。
166. 167. 168. 169. 170. } else if( !strncmp(argv[ 1 ],"use",3) ) { /*use the segment*/
171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. }
15. /* 16. 17. 18. 19. 20. 21. 22. 23. shmat( shmdt( */ ) ) shmctl( ) shmget( ) 创建一个新的共享内存区段 取得一个共享内存区段的描述符 取得一个共享内存区段的信息 为一个共享内存区段设置特定的信息 移除一个共享内存区段 挂接一个共享内存区段 于一个共享内存区段的分离
//must specify
also a letter to write to the buffer
if( argc<3 ) exit( -1 ); user=( char )argv[ 2 ][ 0 ]; //grab the segment shmid=shmget( MY_SHM_ID,0,0 ); block=( MY_BLOCK_T* )shmat( shmid,( const void* )0,0 );
138. }MY_BLOCK_T; 139. int main(int argc,char** argv) 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. { int shmid,ret,i; MY_BLOCK_T* block; struct sembuf sb; char user; //make sure there is a command if( argc>=2 ) { //create the shared memory segment and init it //with the semaphore if( !strncmp(argv[ 1 ],"create",6) ) { //create the shared memory segment and semaphore printf( "Creating the shared memory/n" ); shmid=shmget( MY_SHM_ID,sizeof( MY_BLOCK_T ),( IPC_CREAT|0666 ) );
85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. } else } else }
printf( "%s/n",(char*)mem ); //脱离共享内存区段 ret=shmdt( mem ); if( ret==0 ) printf( "Successfully detached memory /n" ); else printf( "Memory detached failed %d/n",errno );
24. //创建一个共享内存区段,并显示其相关信息,然后删除该内存共享区 25. #include <stdio.h> 26. #include <unistd.h> 27. #include <sys/ipc.h> 28. #include <sys/shm.h> 29. #define MY_SHM_ID 67483 30. int main( 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. { //获得系统中页面的大小 printf( "page size=%d/n",getpagesize( //创建一个共享内存区段 int shmid,ret; shmid=shmget( MY_SHM_ID,4096,0666|IPC_CREAT ); //创建了一个 4KB 大小共享内存区段。指定的大小必须是当前系统架构 //中页面大小的整数倍 if( shmid>0 ) printf( "Create a shared memory segment %d/n",shmid ); //获得一个内存区段的信息 ) ); ) //getpagesize( )
129. #include <unistd.h> 130. #define MY_SHM_ID 34325 131. #define MY_SEM_ID 23234 132. #define MAX_STRING 200 133. typedef struct 134. { 135. 136. 137. int semID; int counter; char string[ MAX_STRING+1 ];
/*##########重点就是使用旗语对共享区的访问###########*/ for( i=0;i<100;++i ) { sleep( 1 ); //设置成 1s 就会看到 a/b 交替出现,为 0 则 a 和 b 连续出现 //grab the semaphore sb.sem_num=0; sb.sem_op=-1; sb.sem_flg=0; if( semop( block->semID,&sb,1 )!=-1 ) { //write the letter to the segment buffer //this is our CRITICAL SECTION block->string[ block->counter++ ]=user;
63. //共享内存区段的挂载,脱离和使用 64. //理解共享内存区段就是一块大内存 65. #include <stdio.h> 66. #include <sys/shm.h> 67. #include <sys/ipc.h> 68. #include <errno.h> 69. #define MY_SHM_ID 67483 70. int main( 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. em ); 83. 84. //向共享区段内存写入数据 strcpy( ( char* )mem,"This is a test string./n" ); { //共享内存区段的挂载和脱离 int shmid,ret; void* mem; shmid=shmget( MY_SHM_ID,0,0 ); if( shmid>=0 ) { mem=shmat( shmid,( const void* )0,0 ); //shmat()返回进程地址空间中指向区段的指针 if( ( int )mem!=-1 ) { printf( "Shared memory was attached in our address space at %p/n",m )
Linux 共享内存编程实例
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. /*共享内存允许两个或多个进程进程共享同一块内存(这块内存会映射到各个进程自己独立的地址空间) 从而使得这些进程可以相互通信。 在 GNU/Linux 中所有的进程都有唯一的虚拟地址空间,而共享内存应用编程接口 API 允许一个进程使 用公共内存区段。但是对内存的共享访问其复杂度也相应增加。共享内存的优点是简易性。 使用消息队列时,一个进程要向队列中写入消息,这要引起从用户地址空间向内核地址空间的一次复制, 同样一个进程进行消息读取时也要进行一次复制。共享内存的优点是完全省去了这些操作。 共享内存会映射到进程的虚拟地址空间,进程对其可以直接访问,避免了数据的复制过程。 因此,共享内存是 GNU/Linux 现在可用的最快速的 IPC 机制。 进程退出时会自动和已经挂接的共享内存区段分离,但是仍建议当进程不再使用共享区段时 调用 shmdt 来卸载区段。 注意,当一个进程分支出父进程和子进程时,父进程先前创建的所有共享内存区段都会被子进程继承。 如果区段已经做了删除标记(在前面以 IPC——RMID 指令调用 shmctl),而当前挂接数已经变为 0, 这个区段就会被移除。 */
106. */ 107. int shmid; 108. //... 109. shmid=shmget( MY_SHM_ID,0,0 ); 110. ret=shmctl( shmid,SHM_LOCK,0 ); 111. if( ret==0 ) 112. printf( "Locked!/n" );
113. //////////////////////////////////////////////////////////////////////// 114. /*使用旗语协调共享内存的例子 115. 116. 117. 118. 119. 120. 121. 使用和编译命令 gcc -Wall test.c -o test ./test create ./test use a & ./test use b & ./test read & ./test re58. 159. 160. 161. 162. 163. 164. 165.