linux

C++如何在Linux上处理并发请求

小樊
33
2025-02-26 07:02:12
栏目: 编程语言

在Linux上使用C++处理并发请求,可以采用多种方法。以下是一些常见的并发模型和相应的实现方式:

1. 多线程

使用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;
}

2. 异步编程

使用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;
}

3. 事件驱动模型

使用libeventlibuv库可以实现事件驱动模型,适用于高并发场景。

使用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;
}

4. 协程

使用Boost.CoroutineC++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;
}

选择哪种方法取决于具体的应用场景和需求。多线程和异步编程适用于大多数情况,而事件驱动模型和协程则适用于高并发和低延迟的场景。

0
看了该问题的人还看了