tl; dr:
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标头内= nc-> Recv(); error: passing 'volatile Netconsole' as 'this' argument discards qualifiers [-fpermissive]
如果重新实例化了实用程序类,则必须在两个线程中更新指向两个线程之间共享的实用程序类实例(Netconsole)的指针,但是将其声明为volatile会产生上述错误。如果仅在一个线程内进行更新,则另一个线程可能仍会使用旧的无效指针。如何确保两者均得到更新,但是通过指针使用方法不会触发上述错误?
扩展信息:
我正在编写的“智能胶合逻辑”库用于在第三方软件和自定义设备之间传递和转换消息。它包含三个基本线程:
处理程序:第3方应用程序的主线程会定期调用我库中的“计算”功能来处理新更新-要发送的数据,已接收的数据发送器线程,该线程将转换并发送处理程序推入发送缓冲区的所有内容一个侦听器线程,该线程将将从设备接收的任何数据转换并将其推入接收缓冲区。发送者线程和侦听器线程都使用相同的实用程序类来处理与设备的网络通信。在初始化时,该类创建与设备的连接,并且两个线程执行阻塞读取或等待分别发送新数据。发生任何问题时,发送方线程将执行所有“维护”工作,而侦听器线程将进入安全状态,等待连接的返回。
现在,由于两个线程共享到设备的一个连接,因此它们都共享通信类的相同实例,作为指向该类的指针。
问题在于重新连接的过程-它涉及利用析构函数和构造函数中已经存在的安全关闭和初始化功能来破坏和创建帮助器类实例。结果,指针改变。没有volatile它,侦听器很可能不会收到更新的指针。使用volatile时,它nc会发出抗议-不必要,因为(指针)不会在随机时刻发生变化-首先会向侦听器通知问题,然后进入安全状态,不对“ nc”执行任何操作,然后通知发件人它已经准备好。只有这样,发送方才执行修复并通知侦听器恢复正常操作。
那么在这种情况下正确的解决方案是什么?