个人主页: 熬夜学编程的小林

系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】

目录

1、线程终止

1.1、pthread_exit() 

1.2、pthread_cancel() 

1.3、pthread_detach() 

2、C++11中thread 


1、线程终止

问题7 : 新线程如何终止?

1、线程函数 return 

2、pthread_exit 

3、main thread call pthread_cancel ,新线程退出结果是-1 

上一弹已经演示了使用函数return终止进程的方式,此处就只介绍后两种方式了!

可不可以使用我们前面学习过的exit函数终止线程呢?

答案是不能,exit是专门用来终止进程的!

const int num = 10;

void *threadrun(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        std::cout << name << " is running" << std::endl;
        sleep(1);
        break; // 1秒后退出循环
    }
    exit(1); // 进程: 专门用来终止进程的,不能终止线程
}

// main函数结束: main thread 结束,表示进程结束!
int main()
{
    std::vector<pthread_t> tids;
    for (int i = 0; i < num; i++)
    {
        // 1.有线程的id
        pthread_t tid;
        // 2.有线程的名字(正确示范)
        char* name  = new char[128];
        snprintf(name, 128, "thread-%d", i + 1);
        pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);
        // 3.保存所有线程的id信息
        tids.emplace_back(tid);
    }
    for(auto tid : tids)
    {
        void* name = nullptr;
        pthread_join(tid,&name);
        std::cout << (const char*)name << " quit" << std::endl;
        delete (const char*)name;
    }
    // 主线程不退
    sleep(100);
    return 0;
}

1.1、pthread_exit() 

pthread_exit()

pthread_exit - 退出一个线程

#include <pthread.h>

void pthread_exit(void *retval);

参数:

  • retval:这是一个指向返回值的指针,该返回值可以被其他线程通过 pthread_join 函数获取。如果线程不需要返回任何值,可以将此参数设置为 nullptr。

代码演示

修改上面新线程函数代码即可!

void *threadrun(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        std::cout << name << " is running" << std::endl;
        sleep(1);
        break; // 1秒后退出循环
    }
    pthread_exit(args); // 专门终止一个线程的!
}

运行结果 

1.2、pthread_cancel() 

 方式三:pthread_cancel

pthread_cancel()

pthread_cancel - 向指定的线程发送取消请求

#include <pthread.h>

int pthread_cancel(pthread_t thread);

参数

  • thread:指定需要取消的目标线程的标识符。

返回值

  • 成功时返回 0
  • 失败时返回非零值,并设置相应的错误码。

代码演示

const int num = 10;

void *threadrun(void *args)
{
    std::string name = static_cast<const char *>(args);
    // 死循环
    while (true)
    {
        std::cout << name << " is running" << std::endl;
        sleep(1);
    }
    pthread_exit(args); // 专门终止一个线程的!
}

// main函数结束: main thread 结束,表示进程结束!
int main()
{
    std::vector<pthread_t> tids;
    for (int i = 0; i < num; i++)
    {
        // 1.有线程的id
        pthread_t tid;
        // 2.有线程的名字(正确示范)
        char* name  = new char[128];
        snprintf(name, 128, "thread-%d", i + 1);
        pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);
        // 3.保存所有线程的id信息
        tids.emplace_back(tid);
    }
    sleep(3);
    // join todo
    for(auto tid : tids)
    {
        pthread_cancel(tid); // 取消新线程
        std::cout << "cancel: " << PrintToHex(tid) << std::endl;
        void* result = nullptr; // 线程被取消线程的退出结果是:-1 #define PTHREAD_CANCELED ((void *) -1)
        pthread_join(tid,&result);
        std::cout << (long long int)result << " quit" << std::endl;
    }
    // 主线程不退
    sleep(100);
    return 0;
}

 运行结果 

问题8: 可不可以不join线程,让它执行完就退出呢?

可以!detach分离

a. 一个线程被创建,默认是joinable的,必须要被join的.

b. 如果一个线程被分离,线程的工作状态分离状态,不需要/不能被join的. 依旧属于进程内部,但是不需要被等待了

1.3、pthread_detach() 

pthread_detach - 将指定的线程设置为分离状态

#include <pthread.h>

int pthread_detach(pthread_t thread);

参数

  • thread:指定要设置为分离状态的线程的标识符。

返回值

  • 成功时返回 0
  • 失败时返回非零值,并设置相应的错误码。
pthread_self - 获取当前线程的线程标识符

#include <pthread.h>

pthread_t pthread_self(void);

返回值

pthread_self 函数返回一个 pthread_t 类型的值,该值表示调用线程的线程标识符。这个标识符是一个不透明的数据类型,通常用于在线程管理、线程间通信和同步等操作中标识当前线程。

不分离线程且终止线程

代码演示

const int num = 10;

void *threadrun(void *args)
{
    // pthread_detach(pthread_self());
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        std::cout << name << " is running" << std::endl;
        sleep(1);
        break; // 1秒后退出循环
    }
    pthread_exit(args); 
}

int main()
{
    std::vector<pthread_t> tids;
    for (int i = 0; i < num; i++)
    {
        pthread_t tid;
        char* name  = new char[128];
        snprintf(name, 128, "thread-%d", i + 1);
        pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);
        tids.emplace_back(tid);
    }
    // join todo
    for(auto tid : tids)
    {
        void* name = nullptr;
        int n = pthread_join(tid,&name);
        std::cout << (const char*)name << " quit...,n: " << n << std::endl;
        delete (const char*)name;
    }
    // 主线程不退
    sleep(100);
    return 0;
}

运行结果  

新线程分离自己

代码演示

const int num = 10;

void *threadrun(void *args)
{
    pthread_detach(pthread_self());
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        std::cout << name << " is running" << std::endl;
        sleep(1);
        break; 
    }
    pthread_exit(args); 
}

int main()
{
    std::vector<pthread_t> tids;
    for (int i = 0; i < num; i++)
    {
        pthread_t tid;
        char* name  = new char[128];
        snprintf(name, 128, "thread-%d", i + 1);
        pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);
        tids.emplace_back(tid);
    }
    // sleep(1);
    // join todo
    for(auto tid : tids)
    {
        void* result = nullptr;
        int n = pthread_join(tid,&result);
        std::cout << (long long int)result << " quit...,n: " << n << std::endl;
    }
    // 主线程不退
    //sleep(100);
    return 0;
}

运行结果  

主线程分离新线程

代码演示

void *threadrun(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        std::cout << name << " is running" << std::endl;
        sleep(1);
        break; 
    }
    pthread_exit(args); 
}

int main()
{
    std::vector<pthread_t> tids;
    for (int i = 0; i < num; i++)
    {
        pthread_t tid;
        char* name  = new char[128];
        snprintf(name, 128, "thread-%d", i + 1);
        pthread_create(&tid, nullptr, threadrun, /*线程的名字*/ name);
        tids.emplace_back(tid);
    }

    for(auto tid : tids)
    {
        pthread_detach(tid);// 主线程分离新线程,前提新线程需要存在
    }

    // 分离后无需join
    for(auto tid : tids)
    {
        void* result = nullptr;
        int n = pthread_join(tid,&result);
        std::cout << (long long int)result << " quit...,n: " << n << std::endl;
    }
    return 0;
}

 运行结果 

2、C++11中thread 

C++11多线程的本质就是对原生线程库接口的封装。

代码演示 

void threadrun(std::string name,int num)
{
    while(num)
    {
        std::cout << name << " num : " << num<< std::endl;
        num--;
        sleep(1);
    }
}

int main()
{
    std::string name = "thread-1";
    std::thread mythread(threadrun,name,10); // 创建线程
    while(true)
    {
        std::cout << "main thhread..." << std::endl;
        sleep(1);
    }
    mythread.join(); // 终止线程
    return 0;
}

运行结果  

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部