线程池的实现

下面是一个考虑了任务优先级、异常处理和线程复用的线程池实现:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

enum class TaskPriority {
    Low,
    Normal,
    High
};

class ThreadPool {
public:
    ThreadPool(size_t numThreads) : stop(false) {
        for (size_t i = 0; i < numThreads; ++i) {
            workers.emplace_back([this] {
                while (true) {
                    std::function task;

                    {
                        std::unique_lock lock(queueMutex);
                        condition.wait(lock, [this] { return stop || !taskQueue.empty(); });

                        if (stop && taskQueue.empty()) {
                            return;
                        }

                        task = std::move(taskQueue.top().task);
                        taskQueue.pop();
                    }

                    try {
                        task(); // Execute the task
                    } catch (const std::exception& ex) {
                        std::cerr << "Exception in thread: " << std::this_thread::get_id() << ", Error: " << ex.what() << std::endl;
                    }
                }
            });
        }
    }

    template 
    auto enqueue(TaskPriority priority, F&& f, Args&&... args) -> std::future::type> {
        using ReturnType = typename std::result_of::type;

        auto task = std::make_shared>(std::bind(std::forward(f), std::forward(args)...));
        std::future res = task->get_future();

        {
            std::unique_lock lock(queueMutex);
            taskQueue.emplace(priority, [task]() { (*task)(); });
        }

        condition.notify_one();

        return res;
    }

    ~ThreadPool() {
        {
            std::unique_lock lock(queueMutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread& worker : workers) {
            worker.join();
        }
    }

private:
    struct Task {
        TaskPriority priority;
        std::function task;

        Task(TaskPriority p, std::function t) : priority(p), task(std::move(t)) {}

        // Custom comparison operator for task priority
        bool operator<(const Task& other) const {
            return priority < other.priority;
        }
    };

    std::vector workers;
    std::priority_queue taskQueue;
    std::mutex queueMutex;
    std::condition_variable condition;
    bool stop;
};

// 示例任务函数
void printNumber(int number) {
    std::cout << "Number: " << number << ", Thread: " << std::this_thread::get_id() << std::endl;
}

int main() {
    // 创建线程池,指定线程数
    ThreadPool pool(4);

    // 提交任务到线程池
    for (int i = 0; i < 10; ++i) {
        auto task = [i] {
            printNumber(i);
        };

        if (i % 2 == 0) {
            pool.enqueue(TaskPriority::High, task);
        } else {
            pool.enqueue(TaskPriority::Normal, task);
        }
    }

    // 等待任务执行完成
    std::this_thread::sleep_for(std::chrono::seconds(1));

    return 0;
}

在这个示例中,线程池类ThreadPool增加了以下功能:

  • TaskPriority枚举:用于表示任务的优先级,分为低、正常和高。
  • Task类型:表示存储任务和优先级的数据结构。
  • TaskPriorityComparator:用于任务优先级比较的比较器结构体。
  • enqueue函数:在提交任务时,需要指定任务的优先级。任务被封装为std::function,并存储在任务队列中。任务执行时,会捕获并处理可能抛出的异常。

main函数中,示例代码提交了10个任务函数printNumber到线程池中进行执行。其中,奇数任务的优先级为TaskPriority::Normal,偶数任务的优先级为TaskPriority::High。最后,通过等待1秒让主线程暂停,以确保所有任务都有机会被线程池中的工作线程执行。

这个示例实现了一个更完整的线程池,考虑了任务优先级、异常处理和线程复用。每个任务都可以设置优先级,并且线程池会根据优先级来执行任务。同时,异常处理机制可以捕获任务执行过程中可能抛出的异常,以便进行相应的处理。线程复用则通过循环执行任务的方式来实现,使得线程可以重复执行多个任务,而不需要频繁地创建和销毁线程。

请注意,这只是一个简单的线程池实现示例,实际使用时可能需要根据具体需求进行更多的功能和细节处理。例如,可以添加更多的线程管理策略,如动态调整线程数量、限制最大并发数等。

你可能感兴趣的:(算法)