我有一个工作线程正在侦听TCP套接字以获取传入流量,并缓冲接收到的主线程要访问的数据(让我们称之为套接字A).然而,工作线程也有做一些常规操作(比如,每秒一次),即使没有数据进来,所以我用select()了超时,让我不需要保持轮询.(请注意,调用receive()在非阻塞套接字,然后睡一秒钟也不好:输入数据应该是立即可用于主线程,即使主线程可能并不总是能够处理它的时候了,因此需要缓冲.)
现在,我还需要能够发信号通知工作线程立即做其他事情; 从主线程,我需要立即让工作线程select()返回.现在,我已经解决了这个问题(方法基本上从这里和这里采用):
在程序启动时,工作线程用于此目的创建数据报(UDP)类型的附加插座,并将其绑定到一些随机端口(我们称之为插座乙).同样,主线程创建一个用于发送的数据报套接字.在其号召select(),工作线程,将列出一个和乙在fd_set.当主线程需要发信号时,它sendto()是相应端口的几个字节localhost.回到工作线程中,如果B保留在fd_setafter select()返回中,则recvfrom()调用并且接收的字节被简单地忽略.
这似乎工作得很好,但我不能说我喜欢这个解决方案,主要是因为它需要为B绑定一个额外的端口,还因为它添加了几个额外的套接字API调用,这可能会失败我猜 - 我不知道真的想要找出每个案件的适当行动.
我认为理想情况下,我想调用一些以A作为输入的函数,除了立即select()返回之外什么都不做.但是,我不知道这样的功能.(我想我可以举例来说shutdown()套接字,但副作用并不是真的可以接受:)
如果这是不可能的,那么第二个最佳选择是创建一个比真正的UDP套接字更糟糕的B,并且实际上并不需要分配任何有限的资源(超出合理的内存量).我想Unix域套接字就可以做到这一点,但是:解决方案不应该比现在的解决方案少得多,尽管一些适量的#ifdef东西都可以.(我主要针对Windows和Linux - 并且顺便编写C++.)
请不要建议重构以摆脱两个单独的线程.这种设计是必要的,因为主线程可能会被长时间阻塞(例如,做一些密集的计算 - 我无法receive()从最里面的计算循环开始定期调用),同时,有人需要缓冲传入的数据(由于我无法控制的原因,它不能是发件人).
现在我正在写这篇文章,我意识到有人肯定会简单地回复" Boost.Asio ",所以我刚刚看了它......但是找不到明显的解决方案.请注意,我也不能(轻松地)影响套接字A的创建方式,但如果需要,我应该可以让其他对象包装它.
作为一个更大的程序(与渲染体积图形相关)的一部分,我有一个小而棘手的子问题,其中任意(但有限)三角形2D网格需要以特定方式进行标记.我刚刚写了一个解决方案(见下文),它对我当时的测试网格来说已经足够好了,尽管我意识到这种方法对于人们可以想到的每个可能的网格都可能不会很好.现在我终于遇到了一个网格,目前的解决方案根本不能很好地执行 - 看起来我应该想出一种完全不同的方法.不幸的是,我似乎无法重置我的思路,这就是为什么我以为我会问这里.
请看下面的图片.(颜色不是问题的一部分;我只是添加它们来改进(?)可视化.而且变化的边缘宽度是一个完全不相关的工件.)

对于每个三角形(例如,橙色ABC和绿色ABD),三个边缘中的每一个都需要被给予两个标签中的一个,例如"0"或"1".只有两个要求:
网格是真正的2D网格,它是有限的:即,它不包裹,并且它具有明确定义的外边界.显然,在边界上很容易满足要求 - 但内部变得更加困难.
直观地说,看起来至少应该存在一个解决方案,即使我无法证明它.(通常有几个 - 其中任何一个都足够了.)
我目前的解决方案是一个非常强力的解决方案(此处仅为完整性而提供 - 可以跳过此部分):
通常这种方法发现只是一对夫妇的迭代内的解决方案,但最近我遇到了该算法趋于结束后,才一两个网上千重试......这显然表明,有可能的网格,它永远不会结束.
现在,我希望有一个确定性的算法,保证总能找到解决方案.计算复杂性不是一个大问题,因为网格不是很大,并且标签基本上只需要在加载新网格时完成,这不会一直发生 - 所以一个算法(例如)指数复杂性应该没问题,只要它有效.(但当然:效率越高越好.)
感谢您阅读此内容.现在,任何帮助将不胜感激!
不幸的是,我无法让Dialecticus建议的方法起作用.也许我没弄错......无论如何,考虑以下网格,起点由绿点表示:
让我们放大一点......
现在,让我们开始算法.在第一步之后,标签看起来像这样(红色="星号路径",蓝色="环形路径"):
到现在为止还挺好.第二步之后:
第三个:
......第四名:
但是现在我们遇到了问题!让我们再做一轮 - 但请注意以洋红色绘制的三角形:
根据我目前的实现,洋红三角的所有边缘都在环形路径上,所以它们应该是蓝色的 - 这实际上是一个反例.现在也许我以某种方式弄错了......但无论如何,最接近起始节点的两条边显然不能是红色; 如果第三个标记为红色,那么似乎解决方案不再符合这个想法.
顺便说一下,这是使用的数据.每行代表一条边,列的解释如下:
我搜索了一会儿但没有在Action Script中找到类似printf的东西.
这使得生成格式化字符串变得有点困难.
我应该为我的用户提供一种从我的OpenGL应用程序主窗口中捕获视频剪辑的简单方法.我正在考虑添加按钮和/或键盘快捷键来启动和停止捕获; 在开始时,我可以要求提供文件名和其他选项,如果有的话.它必须在Windows(XP/Vista)中运行,但我也不想关闭我迄今为止能够保持打开的Linux门.
该应用程序使用OpenGL片段和着色器程序,我最终需要在最终视频中使用这些效果.
在我看来,甚至可能有几种不同的方法可以满足我的要求(但我真的不知道应该从哪里开始):
具有startRecording(filename),stopRecording和captureFrame等函数的编码库.我可以在渲染的每一帧之后调用captureFrame()(或者每隔一秒/三次/无论如何).如果这样做会使我的程序运行速度变慢,那真的不是问题.
一个独立的外部程序,可以通过我的应用程序进行编程控制.毕竟,一个无法控制的独立程序几乎可以满足我的需求...但正如所说,用户操作应该非常简单,我也会欣赏它的无缝性; 我的应用程序通常全屏运行.此外,应该可以作为我的应用程序的安装包的一部分进行分发,我目前正在使用NSIS进行准备.
使用Windows API逐帧捕获屏幕截图,然后使用(例如)此处提到的库之一.似乎很容易找到如何在Windows中捕获屏幕截图的示例; 但是,我会喜欢一个解决方案,它并没有真正迫使我在WinAPI级别上让我的手变得非常脏.
使用OpenGL渲染到屏幕外目标,然后使用库来生成视频.我不知道这是否可能,我担心它可能不是最不痛苦的道路.特别是,我不希望实际渲染采用不同的执行路径,具体取决于是否捕获视频.此外,我会避免在正常的非捕获模式下可能降低帧速率的任何事情.
如果解决方案在任何一个意义上都是免费的,那么这将是很好的,但这并不是一个绝对的要求.一般来说,臃肿越少越好.另一方面,由于超出此问题的原因,遗憾的是,我无法链接任何仅限GPL的代码.
关于文件格式,我不能指望我的用户开始使用谷歌搜索任何编解码器,但只要显示视频对于基本级别的Windows用户来说也很容易,我并不关心格式是什么.但是,如果可以控制输出的压缩质量,那将是很好的.
只是为了澄清:我不需要从像摄像机这样的外部设备捕获视频,也不需要对鼠标移动感兴趣,即使它们也没有伤害.音频没有要求; 应用程序不会产生任何噪音.
我使用Visual Studio 2008编写C++,因为这个应用程序也受益于GLUT和GLUI.我对C++和库中的链接以及那些东西有着深刻的理解,但另一方面,OpenGL对我来说是一个全新的东西:到目前为止,我真的只学到了实际完成工作所必需的部分.
我不急需一个解决方案,所以随时抽出你的时间:)
我明白为什么我们在标准标题中有这个:
#define M_PI 3.14159265358979323846 // pi
Run Code Online (Sandbox Code Playgroud)
但是,我认为拥有这些没有太大好处:
#define M_PI_2 1.57079632679489661923 // pi/2
#define M_PI_4 0.785398163397448309616 // pi/4
#define M_1_PI 0.318309886183790671538 // 1/pi
#define M_2_PI 0.636619772367581343076 // 2/pi
Run Code Online (Sandbox Code Playgroud)
有没有使用这些替代任何优势M_PI/2,M_PI/4,1/M_PI并2/M_PI在实际的代码?(2020 年及以后?)
拼写出来的表达式不是更具可读性吗?
我问的原因有几个。
首先,有一天我不小心把M_PI_2和M_2_PI(甚至可能2 * M_PI)搞混了。花了一段时间才找出问题所在,然后又花了一段时间才找出究竟是什么根本原因。如果您只是阅读使用它们的代码而没有看到定义,那么仍然认为它的含义M_PI_2和M_2_PI含义不是很明显。我为什么要记住那样的东西?那么,可以肯定地说使用这些定义实际上是一种降低代码可读性的反模式吗?
其次,拥有这些定义可能仍然是一个问题,例如在 Windows (Visual C++) 中。与其定义所有这些,我更愿意只定义M_PI, 然后说M_PI/2and 不在M_PI_2代码中。有什么我想念的吗?
我有一个令人烦恼的问题,我可能会以某种方式规避,但另一方面更愿意在它上面,并了解究竟发生了什么,因为看起来这个东西真的要留下来.
这是故事:我有一个简单的OpenGL应用程序可以正常工作:从来不是编译,链接或运行它的主要问题.现在我决定尝试将一些更密集的计算转移到工作线程中,以便可能使GUI更具响应性 - 当然,使用Boost.Thread.
简而言之,如果我在.cpp文件的开头添加以下片段:
#include <boost/thread/thread.hpp>
void dummyThreadFun() { while (1); }
boost::thread p(dummyThreadFun);
Run Code Online (Sandbox Code Playgroud)
,然后我开始得到"这个应用程序无法启动,因为没有找到MSVCP90.dll"尝试启动调试版本.(发布模式正常.)
现在使用Dependency Walker查看可执行文件,他也找不到这个DLL(我猜想这个),我可以看到我们正在寻找它以便能够调用以下函数:
?max@?$numeric_limits@K@std@@SAKXZ
?max@?$numeric_limits@_J@std@@SA_JXZ
?min@?$numeric_limits@K@std@@SAKXZ
?min@?$numeric_limits@_J@std@@SA_JXZ
Run Code Online (Sandbox Code Playgroud)
接下来,我尝试转换每个实例min并max使用宏,但可能找不到对它们的所有引用,因为这没有帮助.(我正在使用一些我没有源代码的外部库.但即使我能做到这一点 - 我认为这不是正确的方法.)
所以,我的问题 - 我猜 - 是:
我在Visual Studio 2008的一个非常简单的安装中首先使用它.然后尝试安装Feature Pack和SP1,但它们也没有帮助.当然也试过几次Rebuild.
我正在使用Boost的预构建二进制文件(v1.36.0).这不是我第一次在这个项目中使用Boost,但这可能是我第一次使用基于单独源的部件.
禁用增量链接无济于事.程序是OpenGL的事实似乎也不相关 - 我在将相同的三行代码添加到一个简单的控制台程序时遇到了类似的问题(但它在抱怨MSVCR90.dll _mkdir,当我更换时)后者boost::create_directory,问题消失!!).它实际上只是删除或添加这三行使程序运行正常或根本不运行.
我不能说我并排理解(甚至不知道这是否相关,但这是我现在所假设的),说实话,我也不是超级感兴趣 - 只要我可以构建,调试和部署我的应用程序......
编辑1:在尝试构建一个无论如何重现问题的精简示例时,我发现该问题与Spread Toolkit有关,Spread Toolkit的使用是我遇到此问题的所有程序的常见因素.(但是,在开始链接Boost之前我从来没有这样做.)
我现在想出了一个让我重现这个问题的最小程序.它由两个编译单元A.cpp和B.cpp组成.
A.cpp:
#include "sp.h"
int main(int argc, char* argv[])
{
mailbox mbox = -1;
SP_join(mbox, "foo");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
B.cpp:
#include …Run Code Online (Sandbox Code Playgroud) 我有一个用Qt编写的MDI应用程序.一些子窗口包括QGLWidgets,即OpenGL上下文.其中最突出的是使用OpenGL顶点和片段着色器来可视化其数据.
我需要以编程方式捕获应用程序主窗口的屏幕截图,当然包括碰巧可见的所有子窗口.起初听起来很容易("肯定已被多次询问过,所以我们只是谷歌吧!"),但经过仔细研究后看起来似乎有点棘手......
现在这是我到目前为止所尝试的:
QPixmap::grabWidget对于使用着色器程序的子窗口不起作用,显然是因为重定向上下文似乎不支持必要的OpenGL扩展.(呈现代码检查关联的上下文是否支持所需的扩展,如果不支持则拒绝继续.)QPixmap::grabWindow 默默地将所有OpenGL上下文留空 - 即使只使用基本原语的那些.QGLWidget::grabFrameBuffer工作,但只捕获特定子窗口的OpenGL上下文,而我想抓住整个应用程序(基本上是Alt+PrtScr在Windows中).我还尝试先做#2,然后对所有子窗口迭代#3,只需将#3的结果复制到#2的图像的正确位置.这非常有效,直到我做了一些子窗口重叠 - 在这种情况下,来自#3的图像覆盖子窗口框架等等.所以这种方法可能需要更多的代码来处理所有令人讨厌的角落情况......
一些额外的背景:一旦我得到截图,我将把它们中的几个放在seqence中以创建视频 - 可能使用ffmpeg.这使得这个问题成为我上一个问题(前一部分)的延续; 只是该应用程序已从单一上下文独立OpenGL程序演变为使用Qt进行整体窗口和UI窗口小部件的东西,并将图形嵌入子窗口.
虽然我当然更喜欢一个不错的Qt-ish跨平台解决方案,但我也愿意考虑采用特定于Windows的黑客攻击.(这应该是可能的,因为我可以看到Alt+PrtScr做了非常正确的事情.)
那么,有什么建议吗?
我对......感兴趣:
我读过他们,但我找不到一个好的比较.特别是我对比较它们的性能基准感兴趣.(也许我应该自己做一个!我希望不会.)
performance messaging high-availability zeromq spread-toolkit
我只是尝试开始传播我的一些工具,我用它来集成不同的传感器数据流程.
在启动传播退出后,出现以下消息:
Conf_load_conf_file: using file: spread.conf
Successfully configured Segment 0 [127.0.0.255:4803] with 2 procs:
localhost: 127.0.0.1
boron: 127.0.1.1
Finished configuration file.
Hash value for this configuration is: 913193717
Conf_load_conf_file: My proc id (129.70.129.5) is not in configuration
Exit caused by Alarm(EXIT)
Run Code Online (Sandbox Code Playgroud)
如消息中所示,我使用以下spread.conf文件来配置我的本地扩展段.
Spread_Segment 127.0.0.255:4803 {
localhost 127.0.0.1
boron 127.0.1.1
}
Run Code Online (Sandbox Code Playgroud)