Отвечу как сам понял вопрос, может быть вообще мимо.
Основная проблема - сильная связность. У вас более низкоуровневый класс SocketServer зачем-то должен знать о существовании InstrumentInterface который им владеет.
Я бы предложил передавать серверу в конструкторе "что-то", куда он сможет писать полученные данные. Простой пример - InstrumentalServer ждет, пока не поступят данные от сервера, и пишет их в девайс. Простой пример, который работает вечно - сервер просыпается раз в секунду, записывает данные и засыпает. При появление данных InstrumentalServer просыпается, пишет их в девайс, и засыпает, снова ожидая входящие данные. Классическая многопоточная задачка же. Удалил методы из интерфейса.
struct MessageQueue
{
std::condition_variable cv;
std::mutex messMtx;
std::queue<std::string> serverMessages;
};
struct AbstractDevice
{
void processData(std::string message)
{
std::cout << message << std::endl;
}
};
class SocketServer
{
public:
SocketServer(MessageQueue& mess)
: out(mess)
{
std::thread t(&SocketServer::processData, this);
t.detach();
}
void processData()
{
for (;;)
{
try
{
std::lock_guard<std::mutex> lock(out.messMtx);
// some output data
out.serverMessages.push("some string 1");
out.serverMessages.push("some string 2");
// completed this iteration
out.cv.notify_one();
}
catch (const std::exception& ex)
{
std::cerr << ex.what() << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
private:
MessageQueue& out;
};
class InstrumentInterface {
public:
virtual ~InstrumentInterface() = default;
};
class InstrumentalServer : public InstrumentInterface
{
public:
InstrumentalServer() = default;
void addDevice(AbstractDevice* dev) { device = dev; };
void waitForMessages()
{
for (;;)
{
std::unique_lock<std::mutex> lock(messages.messMtx);
// sleep until messages received
messages.cv.wait(lock, [this]() {return !messages.serverMessages.empty(); });
while (!messages.serverMessages.empty())
{
device->processData(messages.serverMessages.front());
messages.serverMessages.pop();
}
}
}
private:
MessageQueue messages;
std::unique_ptr<SocketServer> sockServer = std::make_unique<SocketServer>(messages);
AbstractDevice* device;
};
int main()
{
AbstractDevice device;
InstrumentalServer iServer;
iServer.addDevice(&device);
iServer.waitForMessages();
return 0;
}
Можно было бы сделать отдельный мьютекс для девайса, конечно, чтобы надолго мьютекс сообщений не захватывать. Тогда под мьютексом сообщений создаем пустую очередь, свопаем ее с очередью сообщений, освобождаем мьютекс сообщений, захватываем мьютекс девайса, пишем в девайс.
Я правильно понял вопрос?