我使用posix共享内存和posix未命名的信号量和pshared = 1构建了一个客户端服务器应用程序.信号量被放置在共享内存中.程序运行正常,但是当我输入ipcs -m或ipcs -s时,我没有看到我创建的任何共享内存段或信号量.为什么会这样?
/* Server main function for implementing client server program using Posix Shared Memory and Posix Unnamed Semaphores*/
#include "shm_sem.h"
int main(int argc,char ** argv)
{
int fd;
struct shmstruct *ptr;
shm_unlink(MYSHM); // delete shared memory segment, if it already exists
/* create shared memory, set its size, map it and close descriptor */
fd=shm_open(MYSHM,O_RDWR|O_CREAT|O_EXCL,0777);
ptr=mmap(NULL,sizeof(struct shmstruct),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
// truncate the size of shared memory to the size of shmstruct
ftruncate(fd,sizeof(struct shmstruct));
close(fd);
// initialize the semaphores …Run Code Online (Sandbox Code Playgroud) 有没有办法确定如果free()调用某个内存块指针是否会失败?
我有以下情况:有权访问共享资源的线程失败,而它可能处于释放所述资源的状态.现在我需要设计一种安全的方法来清理这个共享资源.
当然,我已经为正常情况分配了资源的所有权,但是上述限制情况呢?
更新:如果我使用其他同步机制,它只会做更多的清理工作,并可能涉及额外的限制条件.如果可能的话,我想限制/避免这些.
解决方案:我最终决定进行重新分解.感谢所有贡献者.你们好棒!
我正在编写一个程序,出于性能原因使用共享内存(套接字和管道作为替代品已被评估,并且它们对我的任务来说不够快,一般来说任何涉及副本的IPC方法都太慢).在共享内存区域中,我正在编写许多固定大小的结构.有一个程序负责将结构写入共享内存,以及许多从中读取的客户端.但是,每个结构中都有一个客户端需要写入的成员(引用计数,它们将以原子方式更新).所有其他成员都应该只读给客户.
由于客户端需要更改该成员,因此无法将共享内存区域映射为只读.但他们也不应该修改其他成员,因为这些程序是用C++编写的,所以内存损坏是可能的.理想情况下,一个客户端应该尽可能地使另一个客户端崩溃.我只担心有问题的客户,而不是恶意客户,所以允许不完美的解决方案.
我可以尝试通过声明他们用作const的标头中的成员来阻止客户端覆盖,但这不会阻止内存损坏(缓冲区溢出,错误的强制转换等)被覆盖.我可以插入金丝雀,但是我必须经常支付检查它们的费用.
我可以在一个单独的映射只写页面中存储指向实际数据的指针,而不是直接存储引用计数成员,同时将结构保留在只读映射页面中.这将起作用,如果我尝试写入指向的数据,操作系统将强制我的应用程序崩溃,但是在尝试编写无锁算法时间接存储可能是不合需要的,因为需要遵循另一级别的间接可以改变是否可以原子地完成.
有没有办法标记较小的内存区域,以便写入它们会导致您的应用程序爆炸?有些平台有硬件观察点,也许我可以激活其中一个内联汇编,但我只能在32位x86上一次只限4个,每个只能覆盖部分结构,因为它们有限到4个字节.这也使我的程序调试痛苦;)
编辑:我发现这张相当令人眼花缭乱的纸张,但不幸的是它需要使用ECC内存和修改过的Linux内核.
c++ reference-counting shared-memory virtual-memory memory-corruption
我的书提供了一个简单的例子,我有点困惑:
它说,"考虑以下程序,并假设细粒度的原子动作正在读取和写入变量:"
int y = 0, z = 0;
co x = y+z; // y=1; z=2; oc;
Run Code Online (Sandbox Code Playgroud)
"如果x = y + z通过使用y加载寄存器然后向其添加z来实现,则x的最终值可以是0,1,2或3."
2?2如何工作?
注意:co启动并发进程,//表示并行运行的语句
concurrency multithreading imperative-programming shared-memory
是否可以在Linux上共享可执行页面以保留空间?我知道有共享内存API可用于在不同进程之间共享内存,但我不认为这是用于那个.
基本上,我希望有一个共享内存区域,可以加载一些常用的共享库.我想让动态链接器链接到预加载(只读)图像,而不是必须将所有共享库图像加载到每个进程(这似乎是浪费).
这可能在Linux内核上吗?Darwin内核使用称为commpages的Mach VM的特性来实现它(dyld共享缓存存储在那里).每个过程都可以访问和共享组合.
只是为了澄清,我知道共享对象(库)是什么.目前,动态链接器在Linux上执行的操作是将所有必需的库加载到程序的地址空间中,这意味着每个链接libc的应用程序(例如)将在其地址空间的某处具有libc的映像.在Darwin上,可以通过在一组共享内存页面上使用 libc的可执行文件(以及其他只读)部分来消除此问题.共享图像的可写部分仍然是分开的.
编辑:我知道ELF格式不支持分离共享库的DATA和TEXT段.我没有使用ELF,我正在使用不同的二进制格式(使用我自己的binfmt内核模块和我自己的动态链接器).如果Linux内核支持类似commpage的功能,我很感兴趣.
编辑2:我能想到这样做的唯一方法是在内核中分配一大块内存并将其映射到每个执行的二进制文件中.第一次执行任何二进制文件时,动态链接器可以取消保护它,用所需数据填充它并保护它.然后不知何故,内核必须确保内存段不被其他任何东西修改,因为它会打开一个巨大的安全漏洞.另一个
给出以下代码:
#include <sys/types.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
int main()
{
int arr[100];
int shmid = shmget(IPC_PRIVATE, sizeof(int), 0600);
int *ptr = shmat(shmid, NULL, 0);
*ptr = 42;
arr[0] = 1;
if (fork())
{
wait(NULL);
printf("%d, %d\n",arr[0],*ptr);
}
else
{
arr[0] = 2;
*ptr = 1337;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:1,1337.
问题:为什么不是2,1337?
如果孩子更新arr并且ptr是他的阻止怎么可能?意思是,父进程更新arr[0]到发生1之前fork(),那为什么更新ptr发生和更新arr[0]值2没有?
最好的祝福
我有一个Windows应用程序运行而不需要提升.我需要为应用程序的所有正在运行的实例之间共享的内存数组创建一个文件映射对象(请注意,其中一些实例可能在不同的登录会话中运行.)
我调用CreateFileMapping API来创建它,使用全局名称,即Global\sharedname使用安全描述符提供all访问权限,everyone但API失败,错误代码为5,或者ERROR_ACCESS_DENIED.
然后我开始阅读文档,发现我的进程需要SeCreateGlobalPrivilege特权.但是当我尝试分配该权限时,AdjustTokenPrivileges返回错误代码ERROR_NOT_ALL_ASSIGNED,我被卡住....
那么这里有什么诀窍,那个疯狂的MS怎么想让我们这样做?
PS.我之前可以使用相同的all access for everyone安全描述符和Global\sharedmutex名称创建一个全局命名的互斥锁(用于对共享内存的同步访问),而不会出现问题.
如果我错了,请纠正我.我的理解是Mac OS X有一个WindowServer进程,它可以合成来自所有应用程序的窗口并在屏幕上绘制最终的合成图像.接下来的问题是WindowServer进程获取其他应用程序的"windows数据"(以某种形式,如位图).它是通过应用程序和WindowServer进程之间的共享内存机制实现的吗?任何关于此的信息或指针/文档都会有所帮助!
另外,iOS是否在这方面实现了类似的?
谢谢!
我正在使用Boost.Interprocess在共享内存中创建一个映射(在本例中从字符串到字符串).在从地图检索期间,编译器似乎想强迫我在托管段中分配内存,以便(不必要地)包含查询项.
我希望能够通过将映射的键与已经在非共享内存中的实例进行匹配来更有效地在共享映射中查找值,而无需执行此额外分配.但是如果我尝试使用std::string或const char *作为地图find方法的参数,它就拒绝编译.(请参阅底部的编译器错误消息).
我是否需要在共享内存密钥类型和非共享内存密钥类型(std::string在此示例中)之间定义某种比较器方法?如果是这样,它应该是什么样的,我应该如何使地图使用它?如果没有,我该怎么办?
这是代码,后面是编译器错误.问题在于底层main().
// shmap2.cpp
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>
//Typedefs of allocators and containers
namespace Shared
{
typedef boost::interprocess::managed_shared_memory
Segment;
typedef boost::interprocess::managed_shared_memory::segment_manager
SegmentManager;
typedef boost::interprocess::allocator< void, SegmentManager >
Allocator;
typedef boost::interprocess::allocator< char, SegmentManager >
CharAllocator;
typedef boost::interprocess::basic_string< char, std::char_traits< char >, CharAllocator >
String;
typedef std::less< String >
StringComparator;
// Definition of the shared map from String to String
// (To …Run Code Online (Sandbox Code Playgroud) 我有一个程序,用shm_open我正在处理的共享内存对象创建.它尝试释放对象shm_unlink,但有时编程错误会导致它在进行调用之前崩溃.在这种情况下,我需要"手动"取消链接共享内存对象,并且我希望能够在普通shell中执行它,而无需编写任何C代码 - 即使用普通的Linux实用程序.
可以吗?这个问题似乎是说,使用unlink(1)上/dev/shm/path_passed_to_shm_open,但联机帮助页都不清楚.