![]() |
1
7
每个对象只能使用一个额外的整数。 将整数初始化为零。当一个进程增加对象的引用计数时,它将其PID转换为整数:
当进程减少引用计数时,它也会这样做。 如果引用计数保留为1,则跟踪整数将等于进程的PID,该进程递增但不递减。
这是因为xor是交换的(
您也可以使用无符号值(定义为换行而不是溢出)-在递增使用计数时添加PID,在递减时减去PID。 |
![]() |
2
1
从根本上讲,共享内存共享状态不是一个健壮的解决方案,我不知道如何使它健壮。 最后,如果一个进程退出,那么它的所有非共享资源都将由操作系统清除。顺便说一下,这是使用进程(fork())而不是线程取得的巨大胜利。 但是,共享资源不是。其他人打开的文件句柄显然没有关闭,而且… 共享内存 .只有在最后一个共享资源的进程退出后,才会关闭共享资源。 假设您在共享内存中有一个PID列表。一个进程可以扫描这个列表以查找僵尸,但是PIDS可以被重用,或者应用程序可能挂起而不是崩溃,或者… 我的建议是在每个进程之间使用管道或其他消息传递原语(有时有一个自然的主从关系,其他时候都需要与所有人交谈)。然后,您可以利用操作系统在进程死亡时关闭这些连接,这样在这种情况下,您的对等方就会收到信号。此外,还可以使用ping/pong超时消息来确定对等机是否挂起。 如果在分析之后,发送这些消息中的实际数据效率太低,那么只要将控制通道保持在操作系统清除的某种流上,就可以使用共享内存作为有效负载。 |
![]() |
3
1
最有效的资源所有权跟踪系统甚至不使用引用计数,更不用说引用持有者列表了。它们只包含关于内存中可能存在的每个数据类型的布局的静态信息,以及每个函数的堆栈框架的形状,并且每个对象都有一个类型指示器。因此,调试工具可以扫描每个线程的堆栈,并递归地跟踪对对象的引用,直到它具有内存中所有对象的映射以及它们如何相互引用为止。当然,具有这种功能的系统也有自动垃圾收集功能。他们需要来自编译器的帮助来获得关于对象和堆栈帧布局的所有信息,并且这些信息实际上不能在所有情况下可靠地从C/C++中获得(因为对象引用可以存储在联盟中,等等),它们在运行时比引用计数更好地执行。 根据您的问题,在“退化”的情况下,除了堆栈上的局部变量之外,进程的所有(或几乎所有)状态都将保存在共享内存中。在这一点上,您将在一个进程中拥有与多线程程序完全相同的功能。或者换句话说,共享足够内存的进程开始变得与线程不可区分。 这意味着您不需要指定问题的“多进程、共享内存”部分。当任何人试图使用引用计数时,都会面临同样的问题。那些使用线程(或者不受限制地使用共享内存;同样的事情)的人面临另一组问题。把两个放在一起,你就会有一个痛苦的世界。 一般来说,如果可能的话,最好不要在线程之间共享可变对象。具有引用计数的对象是可变的,因为可以修改该计数。换句话说,您正在(有效的)线程之间共享可变对象。 我想说的是,如果您对共享内存的使用足够复杂,需要类似于GC的东西,那么您几乎得到了这两个世界中最糟糕的一个:没有过程隔离的优势,过程创建的代价是昂贵的。实际上,您已经编写了一个多线程应用程序,在该应用程序中,您正在线程之间共享可变对象。 本地套接字是一个非常跨平台和非常快速的进程间通信API;它是唯一一个在所有unice和windows上基本相同的接口。所以考虑使用它作为一个最小的通信通道。 顺便问一下,您是否在保存引用的进程中一致地使用智能指针?这是你唯一的希望得到参考计数,甚至一半正确。 |
![]() |
4
0
使用以下
增量
减量
所以您知道所有使用这个对象的进程
你
|
![]() |
5
0
除了自己动手:你还可以使用一些工具,比如aqtime,它有一个引用计数的memchecker。 |
![]() |
danial · 如何在多个字符串的每个位置找到最频繁的字符 2 年前 |
![]() |
Manny · 如何比较Perl中的字符串? 2 年前 |
![]() |
Diret · 获取范围内每个数字的子倍数的算法 2 年前 |
![]() |
Saif · 排序时python如何决定何时调用比较器? 2 年前 |