首页 > 其他分享 >线程一些常用功能总结

线程一些常用功能总结

时间:2023-09-25 12:13:12浏览次数:47  
标签:总结 std 常用 return queue _. 线程 include data

c++11通常单例模式如下:

template <typename T>
class Singleton {
protected:
    Singleton() = default;
    Singleton(const Singleton<T>&) = delete;
    Singleton& operator=(const Singleton<T>& st) = delete;
    static std::shared_ptr<T> _instance;
public:
    static std::shared_ptr<T> GetInstance() {
        static std::once_flag s_flag;
        std::call_once(s_flag, [&]() {
            _instance = std::shared_ptr<T>(new T);
            });
        return _instance;
    }
    void PrintAddress() {
        std::cout << _instance.get() << std::endl;
    }
    ~Singleton() {
        std::cout << "this is singleton destruct" << std::endl;
    }
};
template <typename T>
std::shared_ptr<T> Singleton<T>::_instance = nullptr;

//想使用单例类,可以继承上面的模板,我们在网络编程中逻辑单例类用的就是这种方式
class LogicSystem :public Singleton<LogicSystem>
{
    friend class Singleton<LogicSystem>;
public:
    ~LogicSystem(){}
private:
    LogicSystem(){}
};

线程安全栈

#include <queue>
#include <memory>
#include <mutex>
#include <condition_variable>
template<typename T>
class threadsafe_queue
{
private:
    mutable std::mutex mut;    
        std::queue<T> data_queue;
    std::condition_variable data_cond;
public:
    threadsafe_queue()
    {}
    threadsafe_queue(threadsafe_queue const& other)
    {
        std::lock_guard<std::mutex> lk(other.mut);
        data_queue = other.data_queue;
    }
    void push(T new_value)
    {
        std::lock_guard<std::mutex> lk(mut);
        data_queue.push(new_value);
        data_cond.notify_one();
    }
    void wait_and_pop(T& value)
    {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this] {return !data_queue.empty(); });
        value = data_queue.front();
        data_queue.pop();
    }

    std::shared_ptr<T> wait_and_pop()
    {
        std::unique_lock<std::mutex> lk(mut);
        data_cond.wait(lk, [this] {return !data_queue.empty(); });
        std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
        data_queue.pop();
        return res;
    }
    bool try_pop(T& value)
    {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return false;
        value = data_queue.front();
        data_queue.pop();
        return true;
    }
    std::shared_ptr<T> try_pop()
    {
        std::lock_guard<std::mutex> lk(mut);
        if (data_queue.empty())
            return std::shared_ptr<T>();
        std::shared_ptr<T> res(std::make_shared<T>(data_queue.front()));
        data_queue.pop();
        return res;
    }
    bool empty() const
    {
        std::lock_guard<std::mutex> lk(mut);
        return data_queue.empty();
    }
};

简单线程池实现

#ifndef __THREAD_POOL_H__
#define __THREAD_POOL_H__

#include <atomic>
#include <condition_variable>
#include <future>
#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>

class ThreadPool  {
public:
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool&        operator=(const ThreadPool&) = delete;

    static ThreadPool& instance() {
        static ThreadPool ins;
        return ins;
    }

    using Task = std::packaged_task<void()>;

    ThreadPool(unsigned int num = 5)
        : stop_(false) {
        {
            if (num < 1)
                thread_num_ = 1;
            else
                thread_num_ = num;
        }
        start();
    }
    ~ThreadPool() {
        stop();
    }

    template <class F, class... Args>
    auto commit(F&& f, Args&&... args) -> std::future<decltype(f(args...))> {
        using RetType = decltype(f(args...));
        if (stop_.load())
            return std::future<RetType>{};

        auto task = std::make_shared<std::packaged_task<RetType()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...));

        std::future<RetType> ret = task->get_future();
        {
            std::lock_guard<std::mutex> cv_mt(cv_mt_);
            tasks_.emplace([task] { (*task)(); });
        }
        cv_lock_.notify_one();
        return ret;
    }

    int idleThreadCount() {
        return thread_num_;
    }

private:
    void start() {
        for (int i = 0; i < thread_num_; ++i) {
            pool_.emplace_back([this]() {
                while (!this->stop_.load()) {
                    Task task;
                    {
                        std::unique_lock<std::mutex> cv_mt(cv_mt_);
                        this->cv_lock_.wait(cv_mt, [this] {
                            return this->stop_.load() || !this->tasks_.empty();
                        });
                        if (this->tasks_.empty())
                            return;

                        task = std::move(this->tasks_.front());
                        this->tasks_.pop();
                    }
                    this->thread_num_--;
                    task();
                    this->thread_num_++;
                }
            });
        }
    }
    void stop() {
        stop_.store(true);
        cv_lock_.notify_all();
        for (auto& td : pool_) {
            if (td.joinable()) {
                std::cout << "join thread " << td.get_id() << std::endl;
                td.join();
            }
        }
    }

private:
    std::mutex               cv_mt_;
    std::condition_variable  cv_lock_;
    std::atomic_bool         stop_;
    std::atomic_int          thread_num_;
    std::queue<Task>         tasks_;
    std::vector<std::thread> pool_;
};

#endif  // !__THREAD_POOL_H__

测试相关的代码

int main()
{
    auto &m1 = ThreadPool::instance();
    auto &j = ThreadPool::instance();
    std::cout << "m is " << &m1 << std::endl;
    std::cout << "j is " << &j << std::endl;

    int m = 0;
    ThreadPool::instance().commit([](int& m) {
        m = 1024;
        std::cout << "inner set m is " << m << std::endl;
        }, m);

    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "m is " << m << std::endl;

    std::this_thread::sleep_for(std::chrono::seconds(3));
    ThreadPool::instance().commit([](int& m) {
        m = 1024;
        std::cout << "inner set m is " << m << std::endl;
        }, std::ref(m));
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "m is " << m << std::endl;

    return 1;
}

 

标签:总结,std,常用,return,queue,_.,线程,include,data
From: https://www.cnblogs.com/bwbfight/p/17727657.html

相关文章

  • 《架构即未来》中最常用的15个架构原则
    《架构即未来》这本书的第12章简单阐述了架构设计的一些常用的原则(后面章节会详细阐述)。这些原则中很多都是在架构一开始的设计中就要考虑进去的,这样在出现任何问题时,我们都能够及时的处理,和把问题影响的范围有效的缩小。否则就像我现在的项目,一开始设计时,考虑的很少,出问题时,没有做......
  • Windbg常用命令及分析套路
    自己也在使用windbg分析问题,但是属于刚入门所以转发下大神的总结:https://www.cnblogs.com/fj365/p/13295453.html常用!threadpool查看线程池CPU使用量!threads查看所有托管线程情况!clrstack某个线程托管代码的调用......
  • 变种网络流总结
    最小费用循环流考虑如果费用全部是正的,那么最小费用一定是0.可以强制把所有负边流满,留下反悔边。如果一个点出度大于入度,那么这个点向虚拟汇点连出度减入度,否则从虚拟源点向这个点连入度减出度。无源汇上下界可行流先强制把下界流满,统计每个点的流出和流入。如果流出比流入多......
  • [WPF] 随笔1:MVVM在ViewModel更新Image控件的BitmapImage值时报:必须在与 DependencyObj
    MVVM在ViewModel更新Image控件的BitmapImage值时报:必须在与DependencyObject相同的线程上创建DependencySource原因:必须在UI线程创建BitmapImage=>链接解决方案:使用MemoryStream加载图片,并在UI线程转换成BitmapImage=>链接接下来是我的写法Tip:我用的是MVVMLightViewM......
  • 每日总结——9.24(周日)
    学习工作描述上午:睡了一上午下午:优化黑马点评短信登录和商铺缓存部分,写相关笔记总结晚上:休息总结与反思深入学习了SpringCache中几个注解的使用加深了对Redis使用锁的用法需要抓紧时间,周末不要太贪玩了明日计划上午:工作下午:工作晚上:优化黑马点评,写总结文档......
  • Git常用命令
     1、配置个人身份gitconfig--globaluser.name枝桠[email protected]、生成ssh公钥ssh-keygen-trsa-C"[email protected]"-b4096查看公钥cat~/.ssh/id_rsa.pub3、拉取代码gitclone[-bBRANCH_NAME][email protected]:sw......
  • linux巡检脚本常用
    Linux系统服务巡检脚本原创 李逸皓 运维book思议 2023-09-2418:01 发表于河北收录于合集#linux系统63个#运维103个#shell66个先放个链接,万一有人关注呢运维book思议李小白,一个北漂的运维。希望能够通过本公众号与业内各位大神交流技术问题。186篇......
  • 【RocketMQ】事务实现原理总结
    RocketMQ事务的使用场景单体架构下的事务在单体系统的开发过程中,假如某个场景下需要对数据库的多张表进行操作,为了保证数据的一致性,一般会使用事务,将所有的操作全部提交或者在出错的时候全部回滚。以创建订单为例,假设下单后需要做两个操作:在订单表生成订单在积分表增加本次订......
  • Stream流常用操作
    Stream流是Java8引入的一个新特性,它提供了一种更简洁、更高效的方式来处理集合数据。Stream流的操作可以分为两种:中间操作和终端操作。中间操作(IntermediateOperations):filter(Predicate<T> predicate):根据指定的条件过滤流中的元素。map(Function<T,R>mapper):将流中的每......
  • Java 常用类
    使用Scanner获取键盘输入hasNextXxx()是否还有下个输入项,其中Xxx可以是int、Long等代表基本数据类型的字符串。如果只是判断是否包含下一个字符串,则直接使用hasNext()nextXxx()获取下一个输入项publicclassScannerTest{publicstaticvoidmain(String[]args){......