美文网首页
(八)QT专题-多线程编程-POSIX主动结束和被动结束线程

(八)QT专题-多线程编程-POSIX主动结束和被动结束线程

作者: GoodTekken | 来源:发表于2023-02-13 08:53 被阅读0次

    Page420
    1,线程主动结束
    线程主动结束,一般就在线程函数中使用return语句或调用pthread_exit()函数。函数pthread_exit()的原型声明如下:
    void pthread_exit(void *retval)
    其中,参数retval是线程退出时返回给主线程的值,线程函数的返回类型是 void *。值得注意的是,在main线程中调用pthread_exit(NULL);的时候将结束main线程,但进程并不会立即退出。

    #include "MainWindow.h"
    
    #include <QApplication>
    #include <unistd.h>  //for sleep
    #include <iostream>
    #include <pthread.h>
    
    using namespace std;
    
    #define handle_error_en(en,msg) do {errno = en;perror(msg);exit(EXIT_FAILURE);}while (0);
    
    #define PTHREAD_NUM 2
    
    void *thrfunc1(void *arg)
    {
        static int count = 1;
        pthread_exit((void*)(&count));    //方式一:pthread_exit() 结束线程
    }
    
    void *thrfunc2(void *arg)
    {
        static int count = 2;
        return (void*)(&count);      //方式二:return 结束线程
    }
    
    
    int main(int argc, char *argv[])
    {
    //    QApplication a(argc, argv);
    //    MainWindow w;
    //    w.show();
    
        pthread_t pid[PTHREAD_NUM];
        int retPid;
        int *pRet1;
        int *pRet2;
    
        if((retPid = pthread_create(&pid[0],NULL,thrfunc1,NULL)) != 0)
        {
            perror("create pid first failed");
            return -1;
        }
    
        if((retPid = pthread_create(&pid[1],NULL,thrfunc2,NULL)) != 0)
        {
            perror("create pid second failed");
            return -1;
        }
        if(pid[0] != 0)
        {
            pthread_join(pid[0],(void**)&pRet1);
            printf("get thread 0 exitcode: %d\n",*pRet1);
        }
    
        if(pid[1] != 0)
        {
            pthread_join(pid[1],(void**)&pRet2);
            printf("get thread 1 exitcode: %d\n",*pRet2);
        }
    
        pthread_exit(NULL); // the main thread will exit, but main process will  not
        cout<<"main thread has exited,this line will not run\n"<<endl;
    //    return a.exec();
    }
    

    Output:

    get thread 0 exitcode: 1
    get thread 1 exitcode: 2
    

    2,线程被动结束
    某个线程可能在执行一项耗时的计算任务,而用户没有耐心,希望结束该线程,此时线程要被动地结束。如何被动结束呢?
    一种方法是在同进程的另外一个线程中通过函数pthread_kill()发送信号给要结束的线程,目标线程收到信号后退出;另外一种方法是在同进程的其他线程中通过函数pthread_cancel()来取消目标线程的执行。

    定时取消任务:

    #include "MainWindow.h"
    
    #include <QApplication>
    #include <unistd.h>  //for sleep
    #include <iostream>
    #include <signal.h>
    #include <pthread.h>
    
    using namespace std;
    
    #define handle_error_en(en,msg) do {errno = en;perror(msg);exit(EXIT_FAILURE);}while (0);
    
    #define PTHREAD_NUM 2
    
    static void on_signal_term(int sig)
    {
        cout<<"sub thread will exit"<<endl;
        pthread_exit(NULL);
    }
    
    void *thrfunc(void *arg)
    {
    //接收信号的线程必须先用sigaction函数注册该信号的处理函数。
        signal(SIGQUIT,on_signal_term);
    
        int tm = 50;
        while(true)
        {
            cout<<"thrfunc--left:"<<tm<<"s--"<<endl;
            sleep(1);
            tm--;
        }
        return(void*)0;
    }
    
    
    
    int main(int argc, char *argv[])
    {
    //    QApplication a(argc, argv);
    //    MainWindow w;
    //    w.show();
    
        pthread_t pid;
        int res;
    
        res = pthread_create(&pid,NULL,thrfunc,NULL);
        sleep(5);
        pthread_kill(pid,SIGQUIT);
        pthread_join(pid,NULL);
        cout<<"sub thread has completed,main thread will exit\n";
    
        pthread_exit(NULL); // the main thread will exit, but main process will  not
        cout<<"main thread has exited,this line will not run\n"<<endl;
    //    return a.exec();
    }
    

    Output:

    thrfunc--left:50s--
    thrfunc--left:49s--
    thrfunc--left:48s--
    thrfunc--left:47s--
    thrfunc--left:46s--
    sub thread will exit
    sub thread has completed,main thread will exit
    

    在执行子线程的时候,主线程等了5秒后开始向子进程发送信号SIGQUIT。在子线程中已经注册了SIGQUIT的处理函数on_signal_term()。如果没有注册信号SIGQUIT的处理函数,则将调用默认的处理程序来结束线程所属的进程。

    pthread_kill(pid,0)可以根据返回值判断线程当前状态(不存在,无效,存在)。

    除了通过函数pthread_kill()发送信号来通知线程结束,我们还可以通过函数pthread_cancel()来取消某个线程的运行。
    int pthread_cancel(pthread_t thread);
    其中,参数thread表示要被取消线程(目标线程)的线程ID。

    在死循环中可以加入pthread_testcancel()来让系统测试取消请求。
    另外常见的取消点有printf、pthread_testcancel、read/write、sleep等函数调用的地方。

    相关文章

      网友评论

          本文标题:(八)QT专题-多线程编程-POSIX主动结束和被动结束线程

          本文链接:https://www.haomeiwen.com/subject/rrcfkdtx.html