在Linux上使用C++處理并發請求,可以采用多種方法。以下是一些常見的并發模型和相應的實現方式:
使用C++11標準庫中的<thread>頭文件可以輕松創建和管理線程。
#include <iostream>
#include <thread>
#include <vector>
void handleRequest(int requestId) {
std::cout << "Handling request " << requestId << std::endl;
// 處理請求的代碼
}
int main() {
const int numRequests = 10;
std::vector<std::thread> threads;
for (int i = 0; i < numRequests; ++i) {
threads.emplace_back(handleRequest, i);
}
for (auto& t : threads) {
t.join();
}
return 0;
}
使用C++11的<future>和<async>頭文件可以實現異步編程。
#include <iostream>
#include <future>
#include <vector>
int handleRequest(int requestId) {
std::cout << "Handling request " << requestId << std::endl;
// 處理請求的代碼
return requestId * 2;
}
int main() {
const int numRequests = 10;
std::vector<std::future<int>> futures;
for (int i = 0; i < numRequests; ++i) {
futures.emplace_back(std::async(std::launch::async, handleRequest, i));
}
for (auto& f : futures) {
std::cout << "Result: " << f.get() << std::endl;
}
return 0;
}
使用libevent或libuv庫可以實現事件驅動模型,適用于高并發場景。
libevent#include <event2/event.h>
#include <iostream>
void eventCallback(evutil_socket_t fd, short events, void* arg) {
std::cout << "Event occurred on fd " << fd << std::endl;
// 處理事件的代碼
}
int main() {
struct event_base* base = event_base_new();
if (!base) {
std::cerr << "Could not initialize libevent!" << std::endl;
return 1;
}
struct event* ev = event_new(base, -1, EV_READ|EV_PERSIST, eventCallback, NULL);
if (!ev) {
std::cerr << "Could not create event!" << std::endl;
event_base_free(base);
return 1;
}
event_add(ev, NULL);
event_base_dispatch(base);
event_free(ev);
event_base_free(base);
return 0;
}
libuv#include <uv.h>
#include <iostream>
void onRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
if (nread > 0) {
std::cout << "Data received: " << std::string(buf->base, nread) << std::endl;
// 處理數據的代碼
}
}
int main() {
uv_loop_t* loop = uv_default_loop();
if (!loop) {
std::cerr << "Could not create event loop!" << std::endl;
return 1;
}
uv_tcp_t server;
uv_tcp_init(loop, &server);
struct sockaddr_in addr;
uv_ip4_addr("127.0.0.1", 8080, &addr);
int r = uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
if (r) {
std::cerr << "Bind failed with error code: "<< r << std::endl;
return 1;
}
r = uv_listen((uv_stream_t*)&server, 128, onRead);
if (r) {
std::cerr << "Listen failed with error code: "<< r << std::endl;
return 1;
}
uv_run(loop, UV_RUN_DEFAULT);
uv_loop_close(loop);
return 0;
}
使用Boost.Coroutine或C++20的協程特性可以實現高效的并發處理。
Boost.Coroutine#include <boost/coroutine/all.hpp>
#include <iostream>
struct Task {
struct caller_type;
typedef boost::coroutines::stack_allocation stack_allocation;
Task(boost::coroutines::push_type& sink, stack_allocation* alloc)
: sink_(sink), alloc_(alloc) {}
void operator()() {
for (;;) {
std::cout << "Coroutine running" << std::endl;
sink_(yield);
}
}
private:
boost::coroutines::push_type& sink_;
stack_allocation* alloc_;
};
void runTask() {
boost::coroutines::stack_context sctx = boost::coroutines::fixedsize_stack<>::allocate();
Task task(boost::coroutines::pull_type(sctx), &sctx);
task();
}
int main() {
runTask();
return 0;
}
C++20協程#include <coroutine>
#include <iostream>
struct Task {
struct promise_type {
Task get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
Task handleRequest(int requestId) {
std::cout << "Handling request " << requestId << std::endl;
// 處理請求的代碼
co_return;
}
int main() {
for (int i = 0; i < 10; ++i) {
handleRequest(i);
}
return 0;
}
選擇哪種方法取決于具體的應用場景和需求。多線程和異步編程適用于大多數情況,而事件驅動模型和協程則適用于高并發和低延遲的場景。