当前位置: 首页 > article >正文

【c++】【Linux】【进程】线程终止/崩溃 会导致进程终止/崩溃 吗?

【c++】【Linux】【进程】线程终止/崩溃 会导致进程终止/崩溃 吗?

1.线程终止会导致进程终止吗?

在操作系统中,线程是进程的基本执行单元,一个进程可以包含一个或多个线程。

  • 当一个子线程终止时,进程并不会因此自动终止,其他线程(包括主线程)仍然会继续运行。
  • 主线程都终止时,进程才会结束。

1子线程先结束,主线程继续执行,进程不会终止

1.1使用detach(): 将子线程与主线程分离
#include <iostream>
#include <thread>
#include <chrono>

void worker() {
    std::cout << "子线程开始执行。" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));  // 模拟一些工作
    std::cout << "子线程结束。" << std::endl;
}

int main() {
    std::cout << "主线程开始执行。" << std::endl;

    std::thread t(worker);  // 创建子线程
    t.detach();  // 将子线程与主线程分离,主线程不等待子线程

    std::cout << "主线程继续执行,不等待子线程。" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));  // 主线程继续执行
    std::cout << "主线程结束。" << std::endl;

    return 0;
}
  1. List itemstd::thread t(worker): 这行代码创建了一个新的子线程,执行 worker 函数。
  2. t.detach(): 将子线程与主线程分离,使得主线程不会等待子线程完成。子线程将独立执行。
  3. std::this_thread::sleep_for(std::chrono::seconds(5)): 主线程继续执行,并且睡眠 5 秒,确保子线程有时间执行。
  4. 子线程在 2 秒后结束,主线程在 5 秒后结束。
    运行结果:
    在这里插入图片描述
  • 主线程和子线程各自独立运行,互不干扰。
  • 即使子线程先于主线程结束,主线程仍会继续执行,直到完成其自身的任务。
1.2不使用detach(): 将子线程与主线程分离
#include <iostream>
#include <thread>
#include <chrono>

void worker() {
    std::cout << "子线程开始执行。" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));  // 模拟一些工作
    std::cout << "子线程结束。" << std::endl;
}

int main() {
    std::cout << "主线程开始执行。" << std::endl;

    std::thread t(worker);  // 创建子线程

    std::cout << "主线程继续执行,不等待子线程。" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));  // 主线程继续执行
    std::cout << "主线程结束。" << std::endl;

    return 0;
}

运行结果:
程序抛出了一个异常,但是异常没有被正确处理,但是主线程继续执行
在这里插入图片描述

1.3 使用 join(): 主线程等待子线程结束
#include <iostream>
#include <thread>
#include <chrono>

void worker() {
    std::cout << "子线程开始执行。" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "子线程结束。" << std::endl;
}

int main() {
    std::cout << "主线程开始执行。" << std::endl;

    std::thread t(worker);  // 创建子线程

    // 使用 join() 确保主线程等待子线程完成
    t.join();

    std::cout << "主线程结束。" << std::endl;

    return 0;
}

运行结果:
主线程等待子线程结束,整个进程再结束
在这里插入图片描述

2主线程先结束,其他线程被迫终止,进程也终止

#include <iostream>
#include <thread>
#include <chrono>

void worker() {
    std::cout << "子线程开始执行。" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(10));  // 模拟一些工作
    std::cout << "子线程结束。" << std::endl;
}

int main() {
    std::cout << "主线程开始执行。" << std::endl;

    std::thread t(worker);  // 创建子线程

    std::this_thread::sleep_for(std::chrono::seconds(2));  // 主线程继续执行
    std::cout << "主线程结束。" << std::endl;

    return 0;
}


在这里插入图片描述

  • 主线程先于子线程结束,子线程被迫中止,进程也结束了

2.线程崩溃会导致进程崩溃吗?

  • 子线程崩溃不一定会导致进程崩溃,关键在于如何处理子线程中的错误和异常。

2.1子线程崩溃导致进程崩溃的情况

2.1.1子线程访问非法内存(进程崩溃)

(1)

#include <iostream>
#include <pthread.h>

void* thread_func(void* arg) {
    // 模拟非法内存访问
    int* ptr = nullptr;
    *ptr = 42;  // 触发崩溃
    return nullptr;
}

int main() {
    pthread_t thread;

    // 创建子线程
    if (pthread_create(&thread, nullptr, thread_func, nullptr) != 0) {
        std::cerr << "Failed to create thread." << std::endl;
        return 1;
    }

    pthread_join(thread, nullptr);  // 等待子线程结束

    std::cout << "Main thread continues running." << std::endl;

    return 0;
}

执行结果
在这里插入图片描述
子线程访问了一个空指针,导致了段错误(Segmentation fault),进程崩溃。
(2)

#include <iostream>
#include <thread>
#include <string>

void thread_func(char* str) {
    // 尝试修改只读字符串
    str[0] = 'X';  // 修改字符串的第一个字符
    std::cout << "Thread modified string: " << str << std::endl;
}

int main() {
     char * str = "Hello, World!";  // 常量字符串(只读数据)

    // 创建多个线程来修改该字符串
    std::thread t1(thread_func, std::ref(str));
    std::thread t2(thread_func, std::ref(str));

    t1.join();
    t2.join();

    return 0;
}

执行结果
在这里插入图片描述
子线程访问了无法被修改的常量区数据,导致了段错误(Segmentation fault),进程崩溃。

2.1.2 子线程抛出未捕获的异常(进程崩溃)

如果子线程抛出未捕获的异常,默认情况下会导致调用 std::terminate,从而导致进程崩溃。

#include <iostream>
#include <pthread.h>
#include <stdexcept>

void* thread_func(void* arg) {
    // 模拟子线程中的异常
    throw std::runtime_error("Child thread crashed!");
    return nullptr;
}

int main() {
    pthread_t thread;

    // 创建子线程
    if (pthread_create(&thread, nullptr, thread_func, nullptr) != 0) {
        std::cerr << "Failed to create thread." << std::endl;
        return 1;
    }

    pthread_join(thread, nullptr);  // 等待子线程结束

    std::cout << "Main thread continues running." << std::endl;

    return 0;
}

执行结果
在这里插入图片描述

  • 子线程崩溃而没有适当的处理,std::terminate 会导致进程崩溃
  • 子线程未捕获异常而触发了 std::terminate,导致整个进程崩溃,而不仅仅是子线程。
    这是因为,在多线程程序中,std::terminate 的行为会影响整个进程,即使子线程崩溃,主线程仍然会被中断并导致进程崩溃。

2.2子线程崩溃,但进程继续运行(捕获异常或通过错误处理)

2.2.1子线程异常被捕获,进程不崩溃
#include <iostream>
#include <pthread.h>
#include <stdexcept>

void* thread_func(void* arg) {
    try {
        // 模拟子线程中的异常
        throw std::runtime_error("Child thread crashed!");
    } catch (const std::exception& e) {
        std::cerr << "Caught exception in child thread: " << e.what() << std::endl;
    }
    return nullptr;
}

int main() {
    pthread_t thread;

    // 创建子线程
    if (pthread_create(&thread, nullptr, thread_func, nullptr) != 0) {
        std::cerr << "Failed to create thread." << std::endl;
        return 1;
    }

    pthread_join(thread, nullptr);  // 等待子线程结束

    std::cout << "Main thread continues running." << std::endl;

    return 0;
}

执行结果
在这里插入图片描述

2.2.2 子线程崩溃(但是通过分离线程,主线程继续执行)
#include <iostream>
#include <pthread.h>
#include <stdexcept>

void* thread_func(void* arg) {
    throw std::runtime_error("Child thread crashed!");
    return nullptr;
}

int main() {
    pthread_t thread;

    // 创建子线程
    if (pthread_create(&thread, nullptr, thread_func, nullptr) != 0) {
        std::cerr << "Failed to create thread." << std::endl;
        return 1;
    }

    pthread_detach(thread);  // 分离子线程,主线程继续执行

    std::cout << "Main thread continues running." << std::endl;

    return 0;
}

执行结果
在这里插入图片描述
子线程抛出异常,但因为子线程已经分离,主线程不会被阻塞,进程继续运行,主线程完成执行。

总结

子线程崩溃导致进程崩溃的情况: 如果子线程因为非法内存访问(如空指针解引用)或者未捕获的异常(导致 std::terminate),则进程会崩溃。
子线程崩溃但不导致进程崩溃: 如果子线程抛出异常且异常被捕获,或者使用了 pthread_detach 来分离子线程,主线程仍然能够继续执行,进程不会崩溃。


http://www.kler.cn/a/548992.html

相关文章:

  • matlab汽车动力学半车垂向振动模型
  • 服务器部署DeepSeek,通过Ollama+open-webui部署
  • 轮子项目--消息队列的实现(4)
  • Spring AOP源码解析
  • 传统数组 vs vector和list
  • rust学习笔记1-window安装开发环境
  • 总部年会天府感怀
  • 数据结构 红黑树和set/map
  • docker部署笔记软件memos,通过5320端口访问,如何通过nginx反向代理配置访问?
  • Cherno C++ P55 宏
  • 力扣 最长递增子序列
  • 容器、pod和缓存
  • 第三十三周学习周报
  • 数据结构:图;邻接矩阵和邻接表
  • 进程等待与进程替换
  • 基于Spring Boot的宠物爱心组织管理系统的设计与实现(LW+源码+讲解)
  • 计算机视觉+Numpy和OpenCV入门
  • C++:构造函数,static成员,友元,内部类
  • ASUS/华硕 全系列原厂系统 家庭版 专业版系统 工厂文件 带ASUS Recovery恢复
  • selenium webdriver/chrome driver集合整理130/131/132/133/134/135