C++11多线程的局限

前面有多篇原创博客或译文介绍了C++11多线程的种种用法,但是在实际使用中,笔者却发现了C++11多线程的一些较严重的局限。目前看到的,主要有下面2个:

  1. 不支持类似于pthread_cancel()的功能

  2. 不支持类似于pthread_exit()这样的让当前线程立即退出的功能

因此,C++11的多线程一旦运行起来,很难有简单的方法来让单个指定的线程结束。

这样就会有一些问题,比如,使得编程不方便。举个例子:起N个线程,运行时间各不相同;要求:当第一个线程运行结束时,其他线程立即或尽快停止。

要实现这个需求,可能有多种方法:

  1. 设一个监控线程,它发现第一个线程结束后,负责pthread_cancel其他线程;但因为C++11多线程不支持pthread_cancel类似的功能,因此做不到;

  2. 和方法1类似,设置一个监控线程,当发现需要结束所有其他线程时,利用C++11多线程的thread::native_handle()方法获得工作线程的tid,利用 pthread_kill(tid, SIGTERM) 函数给这些工作线程发送SIGTERM信号,并要求在之前就安装好信号处理函数,而在信号处理函数中调用的就是 pthread_exit(NULL) 了。实例代码如下:

    static void on_signal_term(int sig){
        cout << "on SIGTERM:" << this_thread::get_id() << endl;
        pthread_exit(NULL);
    }
    
    void thread_kill(void){
        signal(SIGTERM, on_signal_term);
        thread* t = new thread( [](){
            while(true){
                ++counter;
            }
        });
        pthread_t tid = t->native_handle();
        cout << "tid=" << tid << endl;
        // 确保子线程已经在运行。
        this_thread::sleep_for( chrono::seconds(1) );
        pthread_kill(tid, SIGTERM);
        t->join();
        delete t;
        cout << "thread destroyed." << endl;
    }

     

  3. 每个线程定期监控一个全局变量。该全局变量初始化为false,第一个结束的线程设置此全局变量为true. 当其他线程定期检查发现该全局变量为true时,因为C++11多线程不支持pthread_exit()类似功能,因此只好立即调用return以结束当前线程. 但是注意,在某些特殊情况下,这样比较麻烦。比如每个线程的线程函数都调用了一个递归函数,那么就需要在这个递归函数中存在定期检查全局变量的代码,并且还需要有逻辑使其发现全局变量为true以后,立即一路返回到顶上。

另外,笔者还尝试了一个失败的方法:类似于方法3的场景,在线程函数中调用功能函数(即那个递归函数),并且在线程函数中调用setjmp,而在功能函数中定期检查上述方法3中的全局变量,一旦为true即调用longjmp函数,以期能够立即返回以结束该线程。但是这里出现的情况是,一旦一个线程调用了longjmp,所有其他进程也都停止了。原因笔者还没有仔细分析,想来是和setjmp、longjmp对多线程的支持是相关的。

以上是最近遇到的有趣问题,略作笔记。

(完)

你可能感兴趣的:(C++,多线程,C++11多线程,C++11)