深入剖析:Linux线程的优雅退出方式 (linux 线程的退出)

在Linux系统中,线程是一种轻量级的进程,它们共享同一进程的地址空间、文件描述符、信号处理程序等资源。线程的创建、销毁、同步和调度都由操作系统内核完成。在多线程编程中,线程的优雅退出方式对程序的稳定性和可维护性至关重要。本文将深入剖析Linux线程的优雅退出方式,帮助开发者更好地掌握线程编程技巧。

一、线程退出的两种方式

在Linux系统中,线程可以通过两种方式退出,分别是非优雅退出和优雅退出。

1. 非优雅退出

当线程执行一个exit()函数、抛出一个异常或者是调用pthread_cancel()函数时,线程将会立即退出,且不会释放已经占用的资源。这是一种非优雅的方式,容易导致资源泄露和内存碎片化。

2. 优雅退出

优雅退出是指在线程退出前,先释放已经占用的资源并按照一定的顺序清理线程的状态。这种方式可以有效地避免资源泄露和内存碎片化,提高程序的稳定性和可维护性。

二、线程优雅退出的实现方式

线程的优雅退出可以通过以下方式实现:

1. pthread_cleanup_push()和pthread_cleanup_pop()

pthread_cleanup_push()和pthread_cleanup_pop()是一对函数宏,可以用于线程清理处理函数的注册和注销。

当线程需要注册一个清理处理函数时,可以使用pthread_cleanup_push()函数宏将清理函数注册到清理处理函数栈。当线程需要退出时,可以使用pthread_cleanup_pop(0)函数宏将清理函数从栈中弹出,并执行清理函数。如果线程不需要执行清理函数,则可以使用pthread_cleanup_pop(1)函数宏将清理函数从栈中弹出,但不执行清理函数。

如下示例代码演示了pthread_cleanup_push()和pthread_cleanup_pop()函数宏的用法:

“`c

#include

#include

void cleanup_handler(void* arg)

{

printf(“Cleanup handler: %s\n”, (char*)arg);

}

void* thread_func(void* arg)

{

pthread_cleanup_push(cleanup_handler, “Hello world”);

printf(“Thread is running\n”);

pthread_cleanup_pop(1);

}

int mn()

{

pthread_t tid;

pthread_create(&tid, NULL, thread_func, NULL);

pthread_join(tid, NULL);

return 0;

}

“`

在上述示例代码中,通过pthread_cleanup_push()宏将清理处理函数注册到清理处理函数栈中,当线程正常退出时,调用pthread_cleanup_pop()宏将清理处理函数从栈中弹出并执行清理函数。

2. 信号处理函数

信号处理函数是一种优雅退出线程的有效方式,它可以在接收到信号时执行清理操作。

在Linux系统中,有一些信号可以用于优雅退出线程,例如SIGINT、SIGTERM、SIGQUIT和SIGUSR1等信号。此外,使用pthread_kill()函数可以向指定线程发送信号。

如下示例代码演示了如何使用信号处理函数优雅退出线程:

“`c

#include

#include

#include

#include

#include

bool g_running = true;

void signal_handler(int signal)

{

printf(“Thread %ld received signal %d\n”, pthread_self(), signal);

g_running = false;

}

void* thread_func(void* arg)

{

signal(SIGINT, signal_handler);

signal(SIGTERM, signal_handler);

while (g_running)

{

printf(“Thread is running\n”);

sleep(1);

}

printf(“Thread is exiting\n”);

}

int mn()

{

pthread_t tid;

pthread_create(&tid, NULL, thread_func, NULL);

pthread_join(tid, NULL);

return 0;

}

“`

在上述示例代码中,将SIGINT和SIGTERM信号的处理函数设置为signal_handler()函数,当接收到这两个信号时,线程会执行signal_handler()函数,将g_running变量设置为false,线程退出。

3. 条件变量

条件变量也可以用于优雅退出线程,它可以让线程在满足一定条件时退出。

在使用条件变量时,需要先获取一个互斥量来保护共享数据的操作。当线程需要等待某个条件时,可以调用pthread_cond_wt()函数来休眠,并使用pthread_cond_signal()函数来唤醒休眠的线程。

如下示例代码演示了如何使用条件变量优雅退出线程:

“`c

#include

#include

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

bool g_running = true;

void* thread_func(void* arg)

{

pthread_mutex_lock(&mutex);

while (g_running)

{

printf(“Thread is running\n”);

pthread_cond_wt(&cond, &mutex);

}

pthread_mutex_unlock(&mutex);

printf(“Thread is exiting\n”);

}

int mn()

{

pthread_t tid;

pthread_create(&tid, NULL, thread_func, NULL);

sleep(1);

pthread_mutex_lock(&mutex);

g_running = false;

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mutex);

pthread_join(tid, NULL);

return 0;

}

“`

在上述示例代码中,将互斥量mutex和条件变量cond初始化,并将g_running变量设置为true。在线程启动后,线程将会进入while循环,并调用pthread_cond_wt()函数休眠,当主线程将g_running变量设置为false时,调用pthread_cond_signal()函数唤醒休眠的线程,线程退出。

4. C++11标准库

在C++11标准库中,提供了一个std::thread类和std::promise类,用于实现多线程编程和线程同步机制。

其中,std::thread类的detach()函数可以使线程成为守护线程,当线程结束时,它会自动退出,并立即释放线程的资源。

如下示例代码演示了如何使用C++11标准库实现优雅退出线程:

“`c++

#include

#include

#include

#include

std::atomic g_running(true);

void thread_func()

{

while (g_running)

{

std::cout

std::this_thread::sleep_for(std::chrono::seconds(1));

}

std::cout

}

int mn()

{

std::thread t(thread_func);

std::this_thread::sleep_for(std::chrono::seconds(1));

g_running.store(false);

t.detach();

return 0;

}

“`

在上述示例代码中,将g_running变量设置为true,并在std::thread类的构造函数中传入线程函数thread_func。在线程启动后,线程将会进入while循环,并调用std::this_thread::sleep_for()函数休眠,当主线程将g_running变量设置为false时,将线程设置为守护线程并调用detach()函数,线程退出。

三、线程优雅退出的注意事项

在优雅退出线程时,需要注意以下事项:

1. 不要在互斥量或信号量的临界区中执行清理操作,否则可能导致死锁或者竞态条件。

2. 不要在优雅退出时释放已经被其它线程占有或者已经被释放的资源。

3. 在线程退出前,务必要清理已经申请的资源,并关闭打开的文件、套接字和数据库连接等资源。

四、

相关问题拓展阅读:

linux下用ssh登录后如何退出?

linux下用ssh登录后退出的方法:在程序中输入exit,如果一次无法退出需要码渗多尝试几次。

1.Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。它支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网迟模历络操作系统。

2.Linux操作系统诞生于1991 年10 月5 日(这是之一次正式向外公码搜布时间)。Linux存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。

3.严格来讲,Linux这个词本身只表示Linux内核,但实际上人们已经习惯了用Linux来形容整个基于Linux内核,并且使用GNU 工程各种工具和数据库的操作系统。

1、linux下用ssh登陆后退出主要有两个命令,Logout和exit。首先使用工具登录一台linux服务器,这里使用ssh登录:

2、首先使用Logout命令尝试退出ssh,这晌裤里可以看到程序是直接退出的,并且会在屏幕上打印出Connection closed by foreign host:

3、最后是使用exit命令尝试退出,这里的效果和用Logout命令退出是一样的宴卜简,当然exit命令弊粗比较短,输入也相对方便一些。以上就是ssh退出登录的方法:

Logout和exit

exit是退出登录 只是退出当前登录的用户而已,段烂租而前面的操作是需要在退出之前进行的。在程序中输入exit,如果一次无法退出需要多尝试几次。

首先使用Logout命令尝试退出ssh,并且会在屏幕上握兆打印出Connection closed by foreign host 更多Linux知识可参考《Linux就该历败这么学》。

exit:在程序中输入exit,如果一次无法退出需要多尝试几次。

或者Logout:首握搜旁先使用Logout命令尝试退出ssh,这里可以看到程序是直接退出的,并且会在屏幕上打印出Connection closed by foreign host 更多Linux知识可参考《Linux就漏宏该这么学段橡》。

linux 线程的退出的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux 线程的退出,深入剖析:Linux线程的优雅退出方式,linux下用ssh登录后如何退出?的信息别忘了在本站进行查找喔。


数据运维技术 » 深入剖析:Linux线程的优雅退出方式 (linux 线程的退出)