我们有一个C++共享库,它使用ZeroC的Ice库来实现RPC,除非我们关闭Ice的运行时,否则我们观察到子进程挂在随机互斥锁上.Ice运行时启动线程,具有许多内部互斥锁并保持打开文件描述符到服务器.
另外,我们有一些我们自己的互斥体来保护我们的内部状态.
我们的共享库被数百个内部应用程序使用,因此我们无法控制进程何时调用fork(),因此我们需要一种方法来安全地关闭Ice并在进程分叉时锁定我们的互斥锁.
在pthread_atfork()上阅读关于处理互斥锁和内部状态的POSIX标准:
或者,某些库可能只能提供一个子例程,它将库中的互斥锁和所有关联状态重新初始化为某个已知值(例如,最初执行映像时的状态).但是,这种方法是不可能的,因为如果互斥锁或锁仍然被锁定,则允许实现失败*_init()和*_destroy()调用互斥锁和锁.在这种情况下,子例程无法重新初始化互斥锁和锁.
在Linux上,此测试C程序从子pthread_atfork()处理程序中的pthread_mutex_unlock()返回EPERM.Linux需要将_NP添加到PTHREAD_MUTEX_ERRORCHECK宏以便进行编译.
这个程序是从这个好的线程链接的.
鉴于在解锁或破坏子进程中的互斥锁在技术上是不安全或合法的,我认为最好有指向互斥锁的指针,然后让子进程在堆上创建新的pthread_mutex_t并让父进程的互斥锁独立,从而拥有小内存泄漏.
唯一的问题是如何重新初始化库的状态,我正在考虑重新设置pthread_once_t.也许是因为POSIX有一个pthread_once_t的初始化程序,它可以重置为初始状态.
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
static pthread_mutex_t *mutex_ptr = 0;
static void
setup_new_mutex()
{
mutex_ptr = malloc(sizeof(*mutex_ptr));
pthread_mutex_init(mutex_ptr, 0);
}
static void
prepare()
{
pthread_mutex_lock(mutex_ptr);
}
static void
parent()
{
pthread_mutex_unlock(mutex_ptr);
}
static void
child()
{
// Reset the once control.
pthread_once_t once = PTHREAD_ONCE_INIT;
memcpy(&once_control, &once, sizeof(once_control));
}
static void
init()
{
setup_new_mutex();
pthread_atfork(&prepare, &parent, &child); …Run Code Online (Sandbox Code Playgroud) ZeroC的ICE(www.zeroc.com)看起来很有趣,我有兴趣查看它并将其与我们使用WCF的现有软件进行比较.特别是,我们的WCF应用程序使用服务器回调(通过HTTP).
谁比较了他们?怎么回事?我对性能方面特别感兴趣,因为互操作性现在并不是我们关注的问题.谢谢!
以下似乎是ZeroC ICE在其自动生成的代码中使用的模式,在我看来,这是他们现在为他们的工具的许多版本制作单例(不确定原因)的方式.各种编译器都没有问题,直到我今天发现Visual Studio 2015 Update 1(VS版本14.0.24720.00,VC++版本19.00.23506)发出错误.在更新1之前,VS2015也没有问题.我不确定这是一个带有Update 1的VS2015 C++编译器中的错误(回归?),还是其他编译器允许滑动的错误(不符合标准的)C++代码.
以下是代码模式的示例:
class Foo {
protected:
virtual ~Foo() {}
friend class Foo_init;
};
class Foo_init {
public:
Foo init;
};
static Foo_init staticFooInit;
Run Code Online (Sandbox Code Playgroud)
VS2015 Update 1会发出以下错误:
example.cpp(13): error C2248: 'Foo::~Foo': cannot access protected member declared in class 'Foo'
example.cpp(3): note: see declaration of 'Foo::~Foo'
example.cpp(1): note: see declaration of 'Foo'
Run Code Online (Sandbox Code Playgroud)
我找到了一个(尚未回答)ZeroC ICE论坛帖子似乎与此相关,但是否则我没有在我的Google搜索中发现任何让我信服这是否是编译器问题或错误代码的信息.我承认我不太了解ZeroC ICE,也没有足够的C++朋友课程来深入了解你能做什么和不能做什么.我希望有更多知识渊博的人可以对此有所了解.
最近我注意到 WebRTC 可能会泄漏真实的 IP 地址,即使是在 VPN 之后。WebRTC 究竟如何才能获得我的真实 IP 地址?
VPN 通常会创建一个新接口,并将所有数据包路由(当我检查路由表时)到该接口。那么 WebRTC 如何获知我的真实 IP 地址呢?是否以某种方式不使用由 VPN 创建的接口?
我读过 WebRTC 使用 STUN、TURN 和 ICE 协议来获取真实 IP 地址。他们如何获得这些信息?
防火墙规则是否能够防止这种泄漏?
编辑:我在 NATed 网络中使用 VPN,这意味着我的计算机不知道我的 ISP 提供的 IP 地址。那么,WebRTC 是否有可能获得它以及如何获得它?
ZeroC ICE与0MQ相比如何?我知道0MQ/Crossroads和DDS非常相似,但似乎无法弄清楚ICE的位置.
我需要快速实现一个系统,将实时市场数据从C++卸载到C#,作为我项目的第一阶段.下一阶段将实现具有基础Pub/Sub设计的基于事件的架构.
我愿意使用TCP ..但系统当前正在一台24核服务器上运行..因此IPC选项会很好.根据我的理解,ICE只是TCP,而DDS和0mq有IPC选项.
目前,我倾向于使用Protobuf与ICE或Crossroads IO.已从OpenSplice DDS网站关闭.我已经对各种选项进行了大量研究,最初考虑的是OpenMPI + boost:mpi,但似乎没有针对.NET的MPI.
我的问题是:
ICE与0MQ相比如何?我无法绕过这个.无法在网上找到任何比较两者的东西.
提前致谢.
........关于我的项目的更多信息:
目前在Windows上使用CMAKE C++,但计划在某个时候转移到CentOS.另一个所需的特性是将tic数据和所有消息存储在"NoSql"数据库中,例如Hbase/Hadoop或HDF5.这些中间件/消息/ pub-sub库中的任何一个都有任何数据库集成吗?
我正在构建一个相当大的项目,基本上由以下内容组成:
服务器1:基于冰的服务.Glacier2用于会话处理.防火墙允许访问Glacier2.
服务器2:通过Glacier2为Ice服务提供的Web界面(读取,公共).通过Glacier 2提供Ice服务的管理界面.
我关心的是网络界面.我想使用Django,因为它都是用python编写的,并且具有非常有用的自动管理面板生成器.
Web界面不访问任何数据库.它通过Glacier2路由器连接到Server#1上的Ice服务,并使用这些服务公开的API来操作数据.
正如您可能知道的那样,Django中的admin生成依赖于Django的ORM的使用; 我没有使用,因为我没有数据库可以访问.
所以我需要生成管理面板,但是,我不需要像ORM那样进行标准数据访问,而是需要拦截任何"db-access"调用并将它们转换为Ice服务调用,然后获取服务的输出(如果有的话,将其转换为ORM通常返回的任何内容并将控制权返回给Django.
谁知道我怎么能这样做?我需要什么子类?任何具体的想法?
谢谢你的时间.
我将在JavaScript中编写自己的STUN实现(带有NodeJS的服务器端),我正在寻找一个基于我的代码的库.
我找到了JSTUN和PJNATH,两者似乎都受到stackoverflow成员的支持.我下载了两者的源代码,PJNATH大约有15,000行代码,而JSTUN小于3000.
一个图书馆比另一个图书馆更完整吗?
我需要服务器和客户端组件,我希望尽可能完整,因为我不想实现TURN(太硬件密集).
我应该看一下更好的图书馆吗?最终我想制作一个完全符合ICE标准的解决方案,但现在STUN已经足够了.
我了解NAT打孔,ICE和SIP VOIP调用的许多细节.关于这些主题,我已经回答了很多关于SO的问题.现在我有一个问题.
我试图理解在呼叫已经建立之后需要为SIP + ICE记录的RE-INVITE消息.
假设VOIP设备的拓扑结构通过SIP发信号并使用ICE(使用STUN/TURN)建立媒体连接.执行ICE连接检查后,两个端点都应确定最佳地址候选配对(IP,端口),并准备好在两个方向上流媒体.
但是我使用SIP和大量文档的经验表明,在被叫方发送200 OK消息以表明他处于应答状态后,调用者将发送一个带有SDP的RE-INVITE,其中包含通过连接性检查选择的特定地址候选者.
描述RE-INVITE与ICE的一些链接在这里和这里(步骤8).Rosenberg的教程(第30页)讨论了RE-INVITE"确保中间盒具有正确的媒体地址".我不确定为什么这很重要.
在收到RE-INVITE时,被叫方是否期望根据收到的新SDP重新配置其ICE堆栈以切换套接字或地址?或者RE-INVITE只是一种协议形式,正式承认呼叫已经建立?如果跳过RE-INVITE步骤并且双方都开始流媒体,那么可能出现什么问题?
我问的原因是因为我正在探索使用ICE而不是SIP的信令服务.我想弄清楚RE-INVITE是否需要模拟.
我正在尝试将视频轨道添加到流中,然后renegotiate()从JsSip 调用.但是,当我从调用者那里做它时工作正常,但是当我从被调用者那里做它时它不起作用(会话终止).我查看了Freeswitch日志,发现了下一行:
2017-05-25 07:41:02.177674 [NOTICE] switch_rtp.c:4591 Activating RTP video ICE: 1Xn5:7JJhZkbbu6MxTEpr 95.29.39.101:55140
2017-05-25 07:41:02.177674 [INFO] switch_core_media.c:3675 Activating video RTCP PORT 55140
2017-05-25 07:41:02.177674 [INFO] switch_core_media.c:3684 Skipping video RTCP ICE (Same as RTP)
2017-05-25 07:41:02.177674 [INFO] switch_core_media.c:6717 RE-SETTING video DTLS
2017-05-25 07:41:02.177674 [INFO] switch_rtp.c:3574 Activate RTP/RTCP video DTLS client
2017-05-25 07:41:02.177674 [INFO] switch_rtp.c:3723 Changing video DTLS state from OFF to HANDSHAKE
2017-05-25 07:41:02.187678 [WARNING] switch_rtp.c:970 sofia/internal/nn9s29br@2cjo9eh03237.invalid got audio stun binding response 487 Role Conflict
2017-05-25 07:41:02.187678 [WARNING] switch_rtp.c:982 audio …Run Code Online (Sandbox Code Playgroud)