假设您在共享内存中有一个引用计数对象.引用计数表示使用该对象的进程数,进程负责通过原子指令递增和递减计数,因此引用计数本身也在共享内存中(它可以是对象的字段,也可以是对象可以包含指向计数的指针,如果他们协助解决这个问题,我愿意接受建议.有时,进程会有一个错误,阻止它减少计数.如何让它尽可能简单地确定哪个过程不会减少计数?
我想到的一个解决方案是给每个进程一个UID(可能是他们的PID).然后当进程递减时,他们将UID推送到与引用计数一起存储的链表上(我选择了一个链表,因为你可以原子地附加到CAS的头部).当您想要调试时,您有一个特殊的进程,它查看共享内存中仍然存在的对象的链接列表,并且列表中没有的任何应用程序的UID是尚未减少计数的那些.
该解决方案的缺点在于它具有O(N)存储器使用,其中N是进程的数量.如果使用共享内存区域的进程数很大,并且您有大量对象,则这很快就会变得非常昂贵.我怀疑有可能是一个中间解决方案,其中有部分固定大小的信息,您可以通过某种方式能够缩小可能的进程列表,即使你不能找出一个一协助调试.或者,如果你能发现它的过程还没有递减当只有一个单一的过程还没有(即无法处理2个或多个进程未能递减计数的检测),这将可能仍然是一个很大的帮助.
(这个问题有更多'人类'解决方案,比如确保所有应用程序使用相同的库来访问共享内存区域,但是如果共享区域被视为二进制接口,并且并非所有进程都是由你不能控制自己.而且,即使所有的应用程序使用相同的库,一个应用程序可能会在库外部出现一个破坏内存的错误,这样就不会减少计数.是的我正在使用不安全的语言C/C++;)
编辑:在单进程情况下,您将拥有控制权,因此您可以使用RAII(在C++中).
algorithm debugging multithreading reference-counting shared-memory
PHP代码应该读取我在下面的C程序中创建的共享内存.但是,无论我将共享内存中的值设置为什么,我都会读取全0.php代码:
<?php
$shm_id = shmop_open(9875, "a", 0, 0);
echo "shmid=".$shm_id." ";
echo "size=".shmop_size($shm_id). " ";
$shm_data = shmop_read($shm_id, 0, 8);
if($shm_data == FALSE)
echo "failed to read";
else
{
echo "data=";
for($i=0;$i < 8;$i++)
{
echo $shm_data[$i];
if($shm_data[$i] == 1)
echo "1";
else if($shm_data[$i] == 0)
echo "0";
else echo "v";
}
}
shmop_close($shm_id);
?>
Run Code Online (Sandbox Code Playgroud)
C代码创建大小为8字节的共享内存块.
我有这个代码来创建共享内存块.我传入9875的密钥,我在php代码中使用它.C代码:
buf1 = allocArray_shared(8, sizeof(unsigned char), &shmid, 9875);
for(i = 0; i < 8; i++)
{
buf1[i] = 0xFF;
}
void* allocArray_shared(int elementCount, int …Run Code Online (Sandbox Code Playgroud) 我正在使用Qt并尝试通过在Linux(ubuntu)中应用此解决方案来实现单实例应用程序.问题是,如果应用程序意外完成(seg.错误或用户杀死它),共享内存将保持连接状态,其他任何进程都无法再次创建它.回想一下QSharedMemory doc:
Unix:QSharedMemory"拥有"共享内存段.当具有附加到特定共享内存段的QSharedMemory实例的最后一个线程或进程通过销毁其QSharedMemory实例而从该段中分离时,Unix内核将释放共享内存段.但是如果最后一个线程或进程在没有运行QSharedMemory析构函数的情况下崩溃,那么共享内存段将在崩溃中幸存下来.
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Ensure single instanse of Cevirgec application
QSharedMemory shared(ApplicationConstants::
if( !shared.create( 512, QSharedMemory::ReadWrite) )
{
// QMessageBox msgBox;
QMessageBox::critical(0, QObject::tr("application is already running!"), QObject::tr("application is already running!"), QMessageBox::Ok, QMessageBox::Ok);
qCritical() << "application is already running!";
exit(0);
}
else {
qDebug() << "application staring...";
}
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
你能在这里建议什么解决方案?在流程最终完成后,如何确保共享内存被清除(或者通常使用的任何动词).我需要像finallyjava这样的主要功能:/
编辑:(解决方案)
我已经通过使用QSharedMemory并捕获SIGSEGV信号然后在信号处理程序中调用sharedMemory.detach()来实现所需的行为.
我有一个numpy数组,我想以一种不涉及副本的方式在一堆python进程之间共享.我使用sharedmem包从现有的numpy数组创建一个共享的numpy数组.
import sharedmem as shm
def convert_to_shared_array(A):
shared_array = shm.shared_empty(A.shape, A.dtype, order="C")
shared_array[...] = A
return shared_array
Run Code Online (Sandbox Code Playgroud)
我的问题是每个子进程都需要访问随机分布在数组中的行.目前,我使用sharedmem包创建一个共享的numpy数组,并将其传递给每个子进程.每个进程还有一个需要访问的行列表idx.当我这样做时,问题在于子进程:
#idx = list of randomly distributed integers
local_array = shared_array[idx,:]
# Do stuff with local array
Run Code Online (Sandbox Code Playgroud)
它创建了数组的副本,而不仅仅是另一个视图.该数组非常大并且在共享之前首先对其进行操作,以便每个进程访问一系列连续的行
local_array = shared_array[start:stop,:]
Run Code Online (Sandbox Code Playgroud)
花了太长时间.
问题:在不涉及复制数组的python进程之间共享对numpy数组的随机访问有什么好的解决方案?
子进程需要只读访问(因此无需锁定访问).
我试图找到一种方法来同步两个共享数据的进程.
基本上我有两个使用共享内存链接的进程.我需要进程A在共享内存区域中设置一些数据,然后进程B读取该数据并对其进行操作.
我期待的事件顺序是:
换句话说,B将阻塞直到它得到"1"信号,得到数据,然后再次阻塞,直到该信号变为"0".
我已经设法使用纯共享内存来模拟它,但是我使用while循环消耗100%的CPU时间,或者我使用带有nanosleep的while循环,有时会错过某些信号.
我已经尝试过使用信号量,但我只能找到一种方法来等待零,而不是一个,并尝试使用两个信号量只是没有用.我不认为信号量是要走的路.
将有许多进程都访问相同的共享内存区域,并且在修改共享内存时需要通知所有进程.
它基本上试图模拟硬件数据和控制总线,其中事件是边缘而不是电平触发.这是我感兴趣的国家之间的转变,而不是国家本身.
那么,任何想法或想法?
一段时间以来,我一直在努力寻找一个似乎无法解决的问题。问题是,当我尝试在Visual Studio 2008下使用Nvidia Nsight调试CUDA代码时,使用共享内存时会得到奇怪的结果。
我的代码是:
template<typename T>
__device__
T integrate()
{
extern __shared__ T s_test[]; // Dynamically allocated shared memory
/**** Breakpoint (1) here ****/
int index = threadIdx.x + threadIdx.y * blockDim.x; // Local index in block. Column major ordering
if(index < 64 && blockIdx.x==0) { // Only work on a few values. Just testing
s_test[index] = (T)index;
/* Some other irelevant code here */
}
return v;
}
Run Code Online (Sandbox Code Playgroud)
当我到达断点1并检查Visual Studio监视窗口内的共享内存时,只有数组的前8个值会更改,其他值保持为空。我希望所有前64个都这样做。

我认为这可能与所有扭曲不同时执行有关。所以我尝试同步它们。我在里面添加了这段代码integrate()
template<typename T>
__device__
T integrate()
{ …Run Code Online (Sandbox Code Playgroud) 我有一堆线程.他们应该访问包含配置数据的单例,该数据在创建单例时初始化一次.因此在第一次访问.因此,对单身人士的进一步行动只是只读的.在这种情况下,我是否需要关键部分?
我需要创建一个包含一些秘密数据的共享内存段.我使用shmget和shmat函数来访问具有0600权限的段.我想只与分叉进程共享这段内存.我试图创建另一个试图访问此段的应用程序,但它不成功,所以它看起来像我想要的那样工作.
但是当我再次运行创建该段的应用程序时,它可以访问该段.这怎么可能?将秘密数据存储到共享内存中是个好主意吗?
我想做的是每个过程都使用全局变量。但是我的过程没有采用全球价值观
import multiprocessing
count = 0
def smile_detection(thread_name):
global count
for x in range(10):
count +=1
print thread_name,count
return count
x = multiprocessing.Process(target=smile_detection, args=("Thread1",))
y = multiprocessing.Process(target=smile_detection, args=("Thread2",))
x.start()
y.start()
Run Code Online (Sandbox Code Playgroud)
我正在输出像
Thread1 1
Thread1 2
.
.
Thread1 9
Thread1 10
Thread2 1
Thread2 2
.
.
Thread2 9
Thread2 10
Run Code Online (Sandbox Code Playgroud)
我想要的是
Thread1 1
Thread1 2
.
.
Thread1 9
Thread1 10
Thread2 11
Thread2 12
.
.
Thread2 19
Thread2 20
Run Code Online (Sandbox Code Playgroud)
我必须要做些什么才能做到这一点?
ECMA-2017(ES8)刚刚在一个月前完成,它引入了SharedArrayBuffer和Atomics.此处的链接表明它们已在某些浏览器中得到支持.
我们知道,它们旨在允许跨线程共享数据.我想知道在浏览器和Node中如何实现这种并行性?我们应该分别使用Web Workers和'cluster'包吗?
javascript parallel-processing multithreading shared-memory ecmascript-2017
shared-memory ×10
c ×3
c++ ×3
linux ×3
debugging ×2
python ×2
algorithm ×1
cuda ×1
javascript ×1
memory-leaks ×1
nsight ×1
numpy ×1
php ×1
qt ×1