我有一个多线程程序(客户端 - 服务器程序,但在这个问题中不一定相关),其中多个线程访问全局队列。有两个队列:msgs_inc
和clients_msg
,其类型为queue<msgInfo>
,其中msgInfo
是我的班级。
第一个线程从客户端收到消息,执行以下操作(相关代码段):
msgInfo message_processed(message_fr_client); //line 1: takes in string
msgs_inc.push(message_processed); //line 2
第二个帖子应该从msgs_inc
检索,处理它们,然后推入clients_msg
。
msgInfo msg_from_queue(msgs_inc); //line 3: retrieve from front of queue
msgs_inc.pop(); //line 4
clients_msg.push(msg_from_queue); //line 5
第三个线程从clients_msg
检索,之后不再需要它。
msgInfo msg_from_queue(clients_msg); //line 6: retrieve from front of queue
clients_msg.pop(); //line 7
我的问题是:
msgInfo
两次,即在推入之前一次,然后在检索之前再次?我应该使用指针或其他东西吗? 感觉可能效率低下,但我不知道另一种方法。msgInfo
实例?我为这种单调乏味道歉 - 我无法找到有关这方面的信息,也无法将具体结论拼凑在一起。
这是我的班级:
class msgInfo
{
public:
msgInfo();
msgInfo(std::string); //creating instance fr string rxed fr client
msgInfo(std::map<int, std::map<int, std::queue<msgInfo>>>, int, int); //creating instance for string to be sent to client
~msgInfo();
private:
int source_id;
int dest_id;
int priority;
std::string payload;
std::list<int> nodePath;
};
第3行和第6行使用的构造函数:
msgInfo::msgInfo(std::queue<msgInfo> outgoing_msg)
{
source_id = outgoing_msg.front().source_id;
dest_id = outgoing_msg.front().dest_id;
priority = outgoing_msg.front().priority;
payload = outgoing_msg.front().payload;
nodePath = outgoing_msg.front().nodePath;
}
答案 0 :(得分:1)
我不使用队列中的构造函数。这是 混乱。写得好得多(也更清晰):
msgInfo msg_from_queue( msgs_inc.front() );
这会调用复制构造函数(因为它会复制);在 你的情况,编译器提供的拷贝构造函数是 足够的。
至于实例化msgInfo
两次,你实际上是
实例化它不止于此,因为它是从你的复制
原始实例进入队列,然后从队列到
第二个线程。这没什么不对。 C ++是
旨在特权使用值语义,并做
否则需要特殊处理。如果它后来证明了这一点
复制是一个性能瓶颈,你可以修复它。
(可能是通过使副本更便宜,而不是通过移动
指针。例如,摆脱那个std::list
。)
如果您使用指针,则必须考虑问题 所有权。你不能只传递本地的地址 变量。并且有两个或多个线程访问相同的数据 如果有人修改数据,则是非法的。
关于你的上一个问题:你不打电话(我猜是的 你是什么意思“应用”)析构函数(至少在使用时) 价值语义)。编译器自动为本地调用它 变量和队列的底层容器调用它 从队列中删除对象时。就此而言,你 不要调用构造函数:当你定义一个对象时, 编译器会为您调用它,并在复制对象时调用它 队列进入队列后执行复制。
最后,您没有显示任何同步逻辑。 我认为这只是因为你被删除了 简化演示,并确保您知道所需 一旦有多个线程就立即同步访问。