C++多线程 增加 event监听和通知
时间: 2025-03-18 21:18:21 浏览: 21
### C++ 中多线程事件监听与通知机制的实现
在 C++ 中,可以利用标准库中的 `std::thread` 和同步工具(如条件变量 `std::condition_variable` 或互斥锁 `std::mutex`)来构建一个多线程的事件监听与通知机制。以下是具体实现的方式:
#### 使用条件变量和互斥锁
通过 `std::condition_variable` 可以让某些线程等待特定事件的发生,而其他线程则负责触发这些事件。
```cpp
#include <iostream>
#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>
class EventListener {
public:
void registerCallback(const std::function<void()>& callback) {
std::lock_guard<std::mutex> lock(mutex_);
callbacks_.push_back(callback);
}
void triggerEvent() {
std::unique_lock<std::mutex> lock(mutex_);
triggered_ = true;
cv_.notify_all(); // 唤醒所有等待的线程
}
private:
bool isTriggered() const { return triggered_; }
void resetTrigger() { triggered_ = false; }
std::vector<std::function<void()>> callbacks_;
mutable std::mutex mutex_;
std::condition_variable cv_;
bool triggered_ = false;
friend class EventHandler;
};
class EventHandler {
public:
EventHandler(EventListener& listener) : listener_(listener) {}
void startListening() {
while (true) {
std::unique_lock<std::mutex> lock(listener_.mutex_);
listener_.cv_.wait(lock, [&]() { return listener_.isTriggered(); });
if (listener_.isTriggered()) {
for (const auto& callback : listener_.callbacks_) {
callback();
}
listener_.resetTrigger();
}
}
}
private:
EventListener& listener_;
};
```
上述代码展示了如何创建一个简单的事件监听器类 `EventListener` 和处理器类 `EventHandler`。
- **注册回调**:任何线程都可以向 `EventListener` 注册回调函数。
- **触发事件**:当某个事件发生时,调用 `triggerEvent()` 方法唤醒所有正在等待该事件的线程并执行已注册的回调函数[^1]。
#### 单线程同时监听多个端口的情况
对于需要在一个线程中同时监听多个端口的需求,可以考虑使用 I/O 复用技术(如 `select`、`poll` 或 `epoll`)。然而,在 Windows 平台上更推荐使用重叠 I/O 或者 IOCP(I/O Completion Ports)。下面是一个基于传统方法的例子——每监听一个端口启动一个新的线程[^2]。
```cpp
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <thread>
#include <vector>
#pragma comment(lib,"Ws2_32.lib")
void listenOnPort(unsigned short port) {
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in service {};
service.sin_family = AF_INET;
service.sin_addr.s_addr = INADDR_ANY;
service.sin_port = htons(port);
bind(serverSocket, reinterpret_cast<SOCKADDR*>(&service), sizeof(service));
listen(serverSocket, SOMAXCONN);
std::cout << "Listening on port: " << port << "\n";
while (true) {
SOCKET clientSocket = accept(serverSocket, nullptr, nullptr);
if (clientSocket != INVALID_SOCKET) {
char buffer[1024];
int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
if (bytesReceived > 0) {
buffer[bytesReceived] = '\0';
std::cout << "Message from client (" << port << "): " << buffer << "\n";
}
closesocket(clientSocket);
} else {
std::cerr << "Accept failed with error: " << WSAGetLastError() << "\n";
}
}
closesocket(serverSocket);
}
int main() {
unsigned short ports[] = {8080, 9090, 7070}; // 需要监听的端口号列表
std::vector<std::thread> threads;
for (auto port : ports) {
threads.emplace_back(listenOnPort, port);
}
for (auto& thread : threads) {
thread.join();
}
WSACleanup();
}
```
此程序会在指定的一组端口上分别开启监听服务,并为每个端口分配独立的工作线程。这种方式适合于少量端口监听场景,但如果端口数量较多,则可能带来较大的性能开销。
---
阅读全文
相关推荐


















