首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在线程末尾调用detach()

在线程末尾调用detach()
EN

Stack Overflow用户
提问于 2020-07-17 11:23:13
回答 1查看 107关注 0票数 0

我有一个类似于下面代码的工作线程。在begin_work中,在创建新的工作线程之前,它将检查工作线程是否正在执行。但是,在调用begin_work之前,当当前线程退出时,end_work将永远不会创建下一个工作线程。

我试着在线程的末尾调用detach,它可以正常工作。在线程末尾调用detach安全吗?或者,在调用end_work之前,如何安全地创建下一个工作线程而不调用begin_work

代码语言:javascript
复制
class thread_worker {
private:
    std::thread worker;
    // ... other menbers

public:
    thread_worker() {};
    ~thread_worker() { end_work(); };

    void begin_work() {
        if (!worker.joinable()) {
            worker = std::thread { &thread_worker::do_work, this };
        }
    }

    void do_work() {
        // ... access other members ...

        if (exit not by notify) {
            worker.detach();    // can I call detach?
        }
    }

    void end_work() {
        if (worker.joinable()) {
            // notify worker to exit
            worker.join();
        } 
    }
};

编辑:

我的目的是在没有阻塞的情况下调用begin_work。如果执行中有一个工作线程,则函数将直接返回或返回is_working错误。否则,创建一个新的工作线程无缝。

因为std::thread::joinable()总是返回true,直到调用joindetach为止。因此,即使当前工作线程已经退出,begin_work的未来调用也永远不会创建新的工作线程。

因此,我需要一个机制来自动分离在线程的末尾。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-17 11:47:48

我尝试在线程结束时调用detach,它运行良好。

在访问worker时存在数据竞争--它是未定义的行为。当begin_work测试worker.joinable()时,do_work可能同时分离它(调用worker.detach())。

您可以在创建它时立即分离它:

代码语言:javascript
复制
worker = std::thread { &thread_worker::do_work, this };
worker.detach();

但是,这会使多个线程同时运行,这与您要求一次运行一个工作线程的要求相矛盾(但为什么只运行一个?)这只会使线程化毫无意义)。

相反,你可以:

代码语言:javascript
复制
void begin_work() {
    end_work();
    worker = std::thread { &thread_worker::do_work, this };
} 

这确保了前面的线程完成。

基于yuor编辑,您只需要检查是否可以不用等待就可以加入--这似乎是您想要分离的原因。你可以用一个原子标志来做这件事。基本上,您只需要处理上面提到的数据竞赛。

代码语言:javascript
复制
class thread_worker {
private:
    std::thread worker;
    std::atomic_bool w_done {true};
    
    // ... other menbers

public:
    thread_worker() {};
    ~thread_worker() { end_work(); };

    void begin_work() {
        if (w_done) {
            end_work();   
            worker = std::thread { &thread_worker::do_work, this };
        }
    }

    void do_work() {
        // ... access other members ...

        w_done = true;
    }

    void end_work() {
        w_done = false;
        if (worker.joinable()) {
            // notify worker to exit
            worker.join();
        } 
    }
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62952941

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档