简体   繁体   English

从另一个线程调用socket-> native_handle()

[英]Calling socket->native_handle() from another thread

I'm writing some asio/tcp server and would like to map native socket descriptor with tcp session identifier. 我正在编写一些asio / tcp服务器,并希望使用tcp会话标识符映射本机套接字描述符。 I'm writing id getter like: 我正在写id getter,如:

inline int get_session_id() { return socket_.native_handle(); }

And calling from second (packets dispatching thread) thread like: 并从第二个(数据包调度线程)线程调用如下:

cout << session_shared_ptr->get_session_id() << endl;

and it writes valid id only for first time, so I guess to something in my implementation is bad. 并且它仅在第一次写入有效的id,所以我想在我的实现中有些东西是坏的。

Can anyone advice me where I did mistake? 任何人都可以告诉我我错在哪里吗?

Firstly, using the native handle as a session id strikes me as a fantasticically bad idea. 首先,使用原生句柄作为会话ID会让我感到非常糟糕。

Not only did you pick an implementation defined backdoor, but also you picked one that is not portable - so your code risks getting different semantics across platforms. 您不仅选择了一个实现定义的后门,而且还选择了一个不可移植的门户 - 因此您的代码可能会跨平台获得不同的语义。

Remember, these are the underlying handles of an abstraction. 请记住,这些是抽象的底层句柄。 The abstractions exist for a reason! 抽象存在是有原因的! Who knows, if your network gets reconnected the native handle may change. 谁知道,如果你的网络重新连接,本机句柄可能会改变。 Nowhere is it documented that you can retain the handle and rely on it to identify the API object. 没有任何地方记录您可以保留句柄并依赖它来识别API对象。


Of course when you do multi threading, you have to keep in mind everything you always do when threading: 当然,当你做多线程时,你必须记住线程时你总是做的一切:

  • synchronize access to shared state and resources 同步对共享状态和资源的访问
  • coordinate the lifetime of such objects 协调这些对象的生命周期
  • guard against starvation and dead/soft locks while doing the above 在做上述事情时防止饥饿和死亡/软锁

Now, you don't speak about synchronization measures, so you have a data race: 现在,您不谈论同步措施,因此您有一个数据竞争:

Thread Safety 线程安全

Distinct objects: Safe. 不同的对象:安全。
Shared objects: Unsafe . 共享对象: 不安全

The standard specifies a data race as Undefined Behaviour ; 该标准将数据竞争指定为未定义行为 ; Anything can happen. 任何事情都可能发生。 You can be thankful your house didn't burn down. 你可以感谢你的房子没烧毁。 Yet. 然而。


All in all: just use a dependable ID. 总而言之:只需使用可靠的ID。 Generate a UUID and store it in the session. 生成UUID并将其存储在会话中。 Use the C++ object identity (ie address ) for identification if you know you don't move sessions with equality. 如果您知道不移动具有相等性的会话,请使用C ++对象标识(即地址 )进行标识。

If you must for some useful reason access the socket from another thread, provide synchronization (mutex - mutual exclusion, or by way of posting to the session strand). 如果您必须出于某种有用的原因从另一个线程访问套接字,请提供同步(互斥 - 互斥,或通过发布到会话链)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM