我正在编写一个C ++ / Qt多线程服务器。因为它只是更大应用程序的一部分,所以我必须将收到的所有数据写入队列。比某人的其他部分处理此信息并给出响应,也将其放入队列中。我想知道是否可以将这个响应放到某个线程中的某个套接字上,因为我到目前为止提出的唯一想法是发送响应到达的信号,唤醒所有线程和他们检查它是否是他们的消息(通过检查套接字描述符)。
我的代码:
thread.h
#pragma once
#include "socket.hpp"
#include <QThread>
class Thread : public QThread
{
Q_OBJECT
public:
Thread(int socketId, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketerror);
private:
int socketDescriptor;
};
thread.cpp
#include "thread.h"
#include <iostream>
Thread::Thread(int socketId, QObject *parent) :
QThread(parent), socketDescriptor(socketId)
{
}
void Thread::run()
{
Socket *tcpSocket = new Socket(socketDescriptor, this);
connect(tcpSocket, SIGNAL(connectionClosed()), SLOT(quit()));
exec();
}
socket.h中
#pragma once
#include <QTcpSocket>
#include <boost/shared_ptr.hpp>
class Message;
class Socket : public QObject
{
Q_OBJECT
public:
Socket(int socketDescriptor, QObject* = 0);
~Socket();
bool isActive();
void emmiter();
signals:
void connectionClosed();
private slots:
void readClient();
void discardClient();
public slots:
void sendResponse(boost::shared_ptr<Message>);
private:
void disconnect();
quint16 nextBlockSize;
QTcpSocket* socket;
};
socket.cpp
void ClientSocket::sendResponse(boost::shared_ptr<Message> msg)
{
if(this->socket->socketDescriptor() == msg->conn.socket)
{
//actuall sending is not important
}
}
这个^以上就是我知道的,但我知道它并不好,特别是如果我有很多线程并且它们都检查socketDescriptor()。此外,我必须从我的Message
类创建一个元对象,以便它可以在信号槽机制中使用d。
我想把信号发送到一个插座。我该怎么做 ?将socket对象放在一个线程中,并通过向线程提供id来调用方法?有什么想法吗?
答案 0 :(得分:2)
我想知道是否可以将此响应放在某个线程中的某个套接字上,因为我到目前为止提出的唯一想法是发送响应到达的信号,唤醒所有线程并且它们检查它是否是它们的消息(通过检查套接字描述符)。
不,那不是你怎么做的。线程就像一个员工。当你去汉堡王时,你不要求简。如果你在柜台看到杰夫,你就不要走过他,然后在后面翻找,让简接受你的订单。如果她忙于客户,但杰夫可以,你不要等Jane。您让第一个可用的收银员接受您的订单。
当您在套接字上接收数据时,拥有一个线程,任何线程,处理该信息。哪个没关系。您不需要强制某个特定的线程来执行此操作。
尽量少考虑线程。他们只是做这项工作的车辆。您应该专注于您想要完成的工作以及执行此操作的代码。如果你必须考虑过度分配工作的机制,你就会做错事。
如果您有收银员(不能做饭)和厨师(无法接受订单),您将始终四处寻找合适的员工来完成工作。但是所有的线程基本上都是平等的,并且同样能够胜任任何工作,所以如果你强迫自己进入它,你只会遇到这种噩梦。