我已经在共享内存中实现了彼得森的互斥算法。我在 c++ 和 java 进程(使用 jni)之间使用共享内存进行通信。问题是我仍然以某种方式看到竞争条件。如果我尝试使用 printf/println 调试它,代码开始运行良好,但是一旦我删除这些打印件,进程就会停止。有人可以请教我问题出在哪里吗?我很确定彼得森算法的实现是正确的。我应该使用 semaphores(semget()) 来代替互斥吗?
c++ java-native-interface locking shared-memory mutual-exclusion
我有一块共享内存,其中包含两个进程之间的字符字符串和整数。
进程 A 写入它,进程 B 读取它(反之亦然)
确保进程 A 不会在进程 B 读取它的同时更新(写入)它的最有效和最有效的方法是什么?(我应该只在共享内存中使用标志,使用信号量,临界区......)
如果您能指出我正确的方向,我将不胜感激。
谢谢。
视窗,C++
我最初的问题在这里,似乎没有人感兴趣。
我决定打破这个乏味的问题并提出以下问题:
char* shared_memory;
shared_memory = (char*) shmat (segment_id, 0, 0);
Run Code Online (Sandbox Code Playgroud)
我们通常会像上面的例子那样获得指向共享内存的指针吗?换句话说,我们应该总是将指针投射到char*更适合我们需要的地方吗?
我正在尝试实现一个基于共享内存的矩阵乘法内核,如CUDA C编程指南中所述.以下是内核:
__global__ void matrixMultiplyShared(float * A, float * B, float * C,
int ARows, int AColumns,
int BRows, int BColumns,
int CRows, int CColumns) {
float * CSub = &C[CColumns * 16 * blockIdx.y + 16 * blockIdx.x];
float CValue = 0;
for (int k = 0; k < (AColumns / 16); ++k) {
float * ASub = &A[AColumns * 16 * blockIdx.y + 16 * k];
float * BSub = &B[AColumns*16*k + 16*blockIdx.y];
__shared__ float As[16][16];
__shared__ float …Run Code Online (Sandbox Code Playgroud) 我有这段代码:
if ((shmid = shmget(key, 512, IPC_CREAT | 0666)) < 0)
{
perror("shmget");
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
每当我将数字设置为高于 2048 时,我都会收到一条错误消息:
shmget: Invalid argument
Run Code Online (Sandbox Code Playgroud)
然而,当我跑步时cat /proc/sys/kernel/shmall,我明白了4294967296。
有谁知道为什么会发生这种情况?提前致谢!
我正在按照此处的示例创建一个可变长度的本地内存数组。内核签名是这样的:
__kernel void foo(__global float4* ex_buffer,
int ex_int,
__local void *local_var)
Run Code Online (Sandbox Code Playgroud)
然后我调用clSetKernelArg本地内存内核参数如下:
clSetKernelArg(*kern, 2, sizeof(char) * MaxSharedMem, NULL)
Run Code Online (Sandbox Code Playgroud)
当MaxSharedMem从查询设置CL_DEVICE_LOCAL_MEM_SIZE。然后在内核内部,我将分配的本地内存拆分为多个数组和其他数据结构,并按照我认为合适的方式使用它们。所有这些都适用于 AMD(gpu 和 cpu)和 Intel 设备。但是,在 Nvidia 上,CL_INVALID_COMMAND_QUEUE当我将这个内核clFinish加入队列然后在队列上运行时,我会收到错误消息。
这是一个生成上述错误的简单内核(本地工作大小为 32):
__kernel
void s_Kernel(const unsigned int N, __local void *shared_mem_block )
{
const ushort thread_id = get_local_id(0);
__local double *foo = shared_mem_block;
__local ushort *bar = (__local ushort *) &(foo[1000]);
foo[thread_id] = 0.;
bar[thread_id] = 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我在本地内存中静态分配相同的数组和数据结构,内核运行良好。有人可以为这种行为和/或解决方法提供解释吗?
我正在尝试将 h264 编码的数据从 gstreamer 共享到另外两个进程(两者都基于 gstreamer)。经过一些研究,我发现唯一的方法是使用 shm 插件。这就是我想要做的
gstreamer--->h264 encoder--->shmsink
shmrc--->process1
shmrc--->process2
Run Code Online (Sandbox Code Playgroud)
我能够从 videotestsrc 和网络摄像头工作中获取原始数据。但是对于 h264 编码的数据,它没有。这是我的测试管道
gst-launch-1.0 videotestsrc ! video/x-raw,width=640,height=480,format=YUY2 !
x264enc ! shmsink socket-path=/tmp/foo sync=true wait-for-
connection=false shm-size=10000000
gst-launch-1.0 shmsrc socket-path=/tmp/foo ! avdec_h264 ! video/x-
raw,width=640,height=480,framerate=25/1,format=YUY2 ! autovideosink
Run Code Online (Sandbox Code Playgroud)
有没有人尝试过使用 h264 编码数据的 shm 插件,请帮忙
我有一个 shell 脚本,它被触发并在 linux 系统上一次又一次地定期运行,比如每 45 分钟一次。我需要在此 shell 脚本的不同运行之间共享某些信息。我可以通过哪些不同的方式来实现这一点?这有点类似于进程间通信。我不想使用磁盘 I/O,所以不创建文件。我可以在内存中创建一些东西,并且可以让它在一段时间内保持活动状态,例如早上 7 点到凌晨 12 点等。在此期间,脚本运行 20 次,并一次又一次地使用/填充该数据结构。脚本下次运行时需要使用上次运行中填充的值。
基本上,我正在寻找像 DB 一样工作但速度更快并且修改成本更低的操作。所以我会将我的数据保存在那个类似 DB 的东西中,并且所有不同的脚本运行都会读取/修改那个东西,而不是一次又一次地去数据库。/dev/shm 看起来不错,除非有人建议更好的选择。
我只是不明白为什么这段代码会按照它的方式工作(而不是我所期望的):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main()
{
int buffer;
int* address;
address=&buffer;
if(fork()==0)
{
*address=27;
printf("Address %ld stores %d\n",(long)address,*address);
exit(0);
}
wait(NULL);
printf("Address %ld stores %d\n",(long)(&buffer),buffer);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么系统会存储不同的变量,即使它们指向相同的内存地址?
注意:我从没想过这段代码会起作用,否则整堆管道和东西都没有任何意义;我只是想了解这里发生了什么。
根据我的观察,如果我在不删除共享内存段的情况下终止我的进程,则该共享内存段将只保留在那里,在 中/dev/shm/xxxx,甚至没有其他进程正在使用它。 这是否意味着内存泄漏?(在我重新启动机器后它会消失)为什么 linux 不提供一种机制来维护共享内存上的引用计数,然后系统可以在没有进程使用它时将其删除。
由于进程可能会崩溃,或者我只是未能捕捉到一些异常......无论如何,当进程异常终止时,我很有可能无法删除该共享内存段。
我的用例:我正在运行几个共享相同内存段进行通信的工作进程。并且没有主节点来协调事情。策略是最后一个退出节点将关闭共享内存段。
顺便说一下,我使用的boost::interprocess是系统级别shm_open而不是系统级别,但我认为它们的行为应该是相同的。