c++11的线程,怎么终止?

u012957077 2016-06-01 10:35:21
假如说我有5个线程同时搜索文件,但是发现耗时很长,想放弃本次搜索,该肿么办?

杀死这5个进程吗,然后等下次搜索的时候再创建5个?

或者创建同步变量,搜索线程每次循环到某个节点都去验证一次这个变量的值?

感觉c++11的线程真不如boost方便,boost直接调用interrupt,线程里面处理异常的时候,跳到开头位置就可以重置线程的状态
...全文
1710 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiqiang01234 2016-06-03
  • 打赏
  • 举报
回复
引用 9 楼 u012957077 的回复:
[quote=引用 8 楼 jiqiang01234 的回复:] 我觉得楼主应该用线程池,或是任务池来做。不需要总是开启和终止线程
我也觉得该用这玩意,就是不会。 不过我现在也没终止线程了,用观察事件打断内部循环,然后用goto,让线程进到最开始的状态。 [/quote] 线程池大概长这个样子

#ifndef _THERAD_POOL_INCLUDE_H_
#define _THERAD_POOL_INCLUDE_H_
#include "singleton_include.h"

typedef std::function<void()> TPTask;
typedef std::vector<TPTask> TPTaskCollection;
typedef std::future<void> TPResult;
typedef std::vector<TPResult> TPResultCollection;

class ThreadPool: public Singleton<ThreadPool>
{
public:
    TPResultCollection Post(const TPTaskCollection& tasks)
    {
        TPResultCollection r;
        std::unique_lock<std::mutex> lock(m_mutex);
        for(const TPTask& t: tasks)
        {
            PkgTask task(t);
            r.push_back(task.get_future());
            m_queue.push(std::move(task));
        }

        m_cv.notify_all();
        return r;
    }

    TPResult Post(const TPTask& t)
    {
        PkgTask task(t);
        TPResult r = task.get_future();

        std::unique_lock<std::mutex> lock(m_mutex);
        m_queue.push(std::move(task));

        m_cv.notify_one();
        return r;
    }

    int GetThreadCount() const
    {
        return THREAD_COUNT;
    }
private:
    explicit ThreadPool(int threadCount):
        THREAD_COUNT(threadCount),
        m_stop(false)
    {
        for(int i = 0; i < THREAD_COUNT; i++)
        {
            m_threads.push_back(std::thread(&ThreadPool::ThreadHandler, this));
        }

    }
    ~ThreadPool()
    {
        m_stop = true;
        m_cv.notify_all();
        for(int i = 0; i < THREAD_COUNT; i++)
        {
            m_threads[i].join();
        }
    }

    void ThreadHandler()
    {
        while(!m_stop)
        {
        	{
	            std::unique_lock<std::mutex> lock(m_mtx);
	            m_cv.wait(lock, [&]{return !m_queue.empty();});        		
        	}

            PkgTaskCollection tasks;
            {
                std::unique_lock<std::mutex> lock(m_mutex);
                while(!m_queue.empty())
                {
                    PkgTask& task = m_queue.front();
                    tasks.push_back(std::move(task));
                    m_queue.pop();
                }
            }

            if(!m_stop)
            {
                for(PkgTask& task: tasks)
                {
                    task();
                }
            }
        }

    }

    friend class Singleton<ThreadPool>;
private:
    const int THREAD_COUNT;
    volatile bool m_stop;
    std::condition_variable m_cv;
    std::mutex m_mtx;

    std::vector<std::thread> m_threads;

    typedef std::packaged_task<void()> PkgTask;
    typedef std::vector<PkgTask> PkgTaskCollection;
    std::queue<PkgTask> m_queue;
    std::mutex m_mutex;
};

#endif // _THERAD_POOL_INCLUDE_H_

u012957077 2016-06-03
  • 打赏
  • 举报
回复
引用 3 楼 dustpg 的回复:
std::atomic就好了,比如std::atomic_bool。 检查频率也不要太高,大致10毫秒检查一次就行了,一般这个要求不高吧。
这个现在也想通了,我现在没退出,设置事件让线程重置状态。 不过我现在每次设置事件,都没什么好办法确定下次任务开始时,所有线程都已经通过检查函数重置了。
u012957077 2016-06-03
  • 打赏
  • 举报
回复
引用 8 楼 jiqiang01234 的回复:
我觉得楼主应该用线程池,或是任务池来做。不需要总是开启和终止线程
我也觉得该用这玩意,就是不会。 不过我现在也没终止线程了,用观察事件打断内部循环,然后用goto,让线程进到最开始的状态。
jiqiang01234 2016-06-02
  • 打赏
  • 举报
回复
我觉得楼主应该用线程池,或是任务池来做。不需要总是开启和终止线程
赵4老师 2016-06-02
  • 打赏
  • 举报
回复
使用多进程。
黑娃 2016-06-02
  • 打赏
  • 举报
回复
我也赞成让线程自己终止,或者设置开关变量,强制终止线程总是容易引发各种讨厌的异常,多说一句,开关变量申明为volatile bool就可以不加锁使用了
七擒关羽 2016-06-02
  • 打赏
  • 举报
回复
最好的方式是让线程自然结束,停止线程中执行程序。 1、如果是循环设置停止标志开关,可以是全局,使所有线程共享,参考简单的读写线程这种多线程同步 2、如果是普通程序,关闭执行程序句柄,例如socket的读写的阻塞模式。 当然有强制结束方式,但是会可能造成线程资源泄露或影响系统的其他操作,完全结束执行的进程,系统会自己回收。
renwotao2009 2016-06-01
  • 打赏
  • 举报
回复
设置停止标志变量,各个线程注意加锁
dustpg 2016-06-01
  • 打赏
  • 举报
回复
std::atomic就好了,比如std::atomic_bool。 检查频率也不要太高,大致10毫秒检查一次就行了,一般这个要求不高吧。
u012957077 2016-06-01
  • 打赏
  • 举报
回复
引用 1 楼 dustpg 的回复:
其实杀线程很不安全,微软都不推荐这么干,所以乖乖地join吧。 杀进程安全地多,这也是chrome之类浏览器多进程的原因, 64位地址用都用不完为什么还要多进程,这不就是安全么...
如果不能杀的话,就必须要从主线程控制所有查找线程的状态。 就要多加一些同步的变量,控制起来太麻烦了。 volentile int seq; inline void interrupt(){++seq;} inline void check(){ if(cur_seq != seq) throw CException() ;} 现在我是不断在查找线程的循环体中调用check(), 如果加锁保护seq可能影响性能,不加说不定有同步错误
dustpg 2016-06-01
  • 打赏
  • 举报
回复
其实杀线程很不安全,微软都不推荐这么干,所以乖乖地join吧。 杀进程安全地多,这也是chrome之类浏览器多进程的原因, 64位地址用都用不完为什么还要多进程,这不就是安全么...

64,640

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧