- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
长话短说:
class Controller
{
public:
volatile Netconsole* nc;
void init(); //initialize the threads
void calculate(); // handler for the "mothership app"
void senderThreadLoop(); //also calls reinitNet() if connection is broken.
void listenerThreadLoop();
inline void reinitNet(){ delete nc; nc = new Netconsole(); }
}
//里面 Json::Value header = nc->Recv();
错误:将“volatile Netconsole”作为“this”参数传递会丢弃限定符 [-fpermissive]
如果实用程序类被重新实例化,则指向两个线程之间共享的实用程序类 (Netconsole) 实例的指针必须在两个线程内更新,但将其声明为 volatile 会产生上述错误。如果它只在一个线程内更新,另一个线程可能仍然使用旧的、无效的指针。如何确保它在两者中都已更新但通过指针使用方法不会触发上述错误?
扩展信息:
我正在编写的“智能胶合逻辑”库用于在第 3 方软件和自定义设备之间传递和转换消息。它由三个基本线程组成:
发送者和监听者线程都使用相同的实用程序类来处理与设备的网络通信;初始化后,该类创建到设备的连接,两个线程分别执行阻塞读取或等待新数据发送。如果出现任何问题,发送方线程将执行所有“维护”工作,而监听方线程将进入安全状态,等待连接恢复。
现在,由于这两个线程共享一个到设备的连接,它们都共享通信类的同一个实例,作为指向该类的指针。
问题出在重新连接的过程中——它涉及利用析构函数和构造函数中已经存在的安全关闭和初始化来销毁和创建辅助类实例。结果指针改变了。如果没有 volatile
,监听器很可能不会收到更新后的指针。对于 volatile,它会抗议 - 不必要的,因为 nc
(指针)不会在随机时刻改变 - 首先会通知监听器有问题,然后它会进入安全状态,但不会对“nc”执行任何操作并通知发送者它已准备就绪。只有这样,发送方才执行修复并通知收听方恢复正常操作。
那么在这种情况下正确的解决方案是什么?
最佳答案
您需要的是一系列操作。生产线程有 2 个相关操作:“初始化新的 Netconsole
”和“写入指针”。消费线程还有两个操作:“读指针”和“使用新的Netconsole
对象”。这 4 个操作必须按完全的顺序排列,以便更新可见。
到目前为止,实现这一目标的最简单方法是两个内存屏障。写入屏障(指针写入上的 std::memory_order_release
)防止前两个操作被重新排序,读取屏障(指针加载上的std::memory_order_acquire
)防止最后两个操作被重新排序。
由于这两个线程独立运行,您的程序正确性不应取决于特定对象更新是否发生在特定对象使用之前。更新线程可能只是有点慢,这不应该破坏您的程序。因此,写入和读取之间的第三次排序并不真正相关,您不应该尝试“修复”它。
总结一下:是的,这 4 个操作必须以完全正确的顺序发生才能使结果可见,但是如果第二个和第三个操作是重新排序,然后更新对消费线程完全不可见。这是一个原子更新,全有或全无。
还有清理旧对象的问题。生产线程不能假设消费线程已经看到指针更新。必须有同步以确保两个线程都同意旧对象未被使用。最简单的是如果生产线程在创建新对象后严格不使用旧对象(内存屏障在这里有帮助),并且消费线程一知道有新对象就清理旧对象(因为那严格发生在读取屏障之后,因此发生在写入屏障之后,进而发生在生产线程最后一次使用之后)
关于c++ - 在线程之间安全地分发指针更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32567607/
在我的 java 代码中,我做了类似的事情: int sleep = 0; sleep(sleep); sleep++; 被bos指出不好。它不能在 php 中正常工作。 在 java 中使用上述代码
我有一个程序使用第 3 方库进行一些计算,我在与主应用程序不同的线程上启动该程序。不幸的是,此计算可能需要很长时间,并且不提供进度更新和取消的接口(interface)。 为了拥有这样的界面,我想创建
C++ 是否有任何等效于 python 的函数 os.path.join?基本上,我正在寻找将文件路径的两个(或多个)部分组合在一起的东西,这样您就不必担心确保这两个部分完美地结合在一起。如果它在 Q
我正试图站起来(非商业)web application使用 neo4j Community 3.5.2 作为后端。 应用程序以两种方式与图形交互: 服务器端(安全的)用 flask 编写新的节点和关系
我正在开发一个将有许多外部用户的在线应用程序。至于现在,我的连接方法是为所有用户托管一个中央数据库,而他们从自己的服务器文件连接。 方法: PHP 连接文件(托管在他们的服务器上;文件由我提供) >>
我创建了一个将所有事件通知代码转换为字符串的函数。真的很简单。 我有一堆常量,比如 const _bstr_t DIRECTSHOW_MSG_EC_ACTIVATE("A video window i
我想将(附加)信息从过滤器传递到资源。我目前尝试这样做的方式是,在 Filter 中: getContext().getAttributes().put("additionalInformation"
我想计算转换系数。为此,我必须除以例如的最大值。 ushort 为 uchar 的最大值。 我想通过将参数传递给函数或类型名来动态地执行此操作。然后我想选择最大值并执行计算。 有两个问题: 如何动态选
我希望我的用户在用 Java 请求列表时能够编写自己的过滤器。 选项 1) 我正在考虑将 JavaScript 与 Rhino 结合使用。 我将用户的过滤器作为 javascript 字符串获取。然后
(安全地)提供来自不同域的图像是否符合 PCI 标准?我搜索了 PCI DSS 2.0 PDF,但没有找到任何引用资料。 最佳答案 图像不符合 PCI 合规性。 PCI DSS covers the
我们正在将 spring 和 hibernate 用于 web 应用程序:该应用程序有一个购物车,用户可以在其中放置商品。为了保存不同登录名之间要查看的项目,购物车中的项目值存储在表中。提交购物车时,
我正在为多个客户创建一个具有电子商务元素的 Rails 应用程序 - 我希望这些客户能够在管理区域中指定计算运费的公式;因为方法可能不同。 让我们假装一下,我允许他们输入 ruby 代码,然后我稍
我正在 Eclipse 中开发一个 Java 项目,使用 Maven 构建和管理依赖项。该项目分布在 5 个 Eclipse 项目中,其中一个是父 POM。我正在研究基于另一个团队实现的更复杂服务器的
我想在 ADO.NET 数据服务中存储每线程数据。在线程特定的静态变量上使用 ThreadStatic 属性是否安全,或者我会遇到问题吗?我担心的是,我的 ThreadStatic 变量在请求完成并且
Stackoverflow 上至少有一篇与此主题相关的帖子:Generate password in python 你会发现这个主题甚至在 PEP 中也受到了一些批评。这里提到:https://www
对于我工作中的一个项目,我需要创建一个独立的 Python 安装(来自源代码)。然而,完整的目录占用大约 90MB 的磁盘空间,虽然不多,但太多了,无法一遍又一遍地复制。 我可以从自定义 python
例如,我有一张学生表,我有一本 Python 字典 mydict = {"fname" : "samwise", "lname" : "gamgee", "age" : 13} 我怎样才能安全地生成一
我经常在代码中遇到使用 memset 手动零初始化的 POD 结构,如下所示: struct foo; memset(&foo, 0, sizeof(foo)); 我检查了 C++11 标准,它说:“
我是一名优秀的程序员,十分优秀!