Linux系统编程-(pthread)线程的使用案例(分离属性、清理函数等)

简介: 这篇文章介绍Linux下线程的创建与基本使用案例,主要是案例代码为主;相关的函数详细介绍在上篇文章里已经介绍过了。

这篇文章介绍Linux下线程的创建与基本使用案例,主要是案例代码为主;相关的函数详细介绍在上篇文章里已经介绍过了。

1. 案例代码: 线程的创建

下面这份代码演示如何创建线程。在编译的时候需要加上-lpthread

函数原型:

#include <pthread.h>
int pthread_create
(
pthread_t *thread, 
const pthread_attr_t *attr,
void *(*start_routine) (void *), 
void *arg
);

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>

//[wbyq@wbyq linux_c]$ gcc app.c -lpthread

/*
线程工作函数
*/
void *thread_work_func(void *dev)
{
    int i;
    for(i=0;i<5;i++)
    {
        sleep(1);
        printf("子线程正在运行.%d \n",i);
    }
    //终止当前线程执行
    pthread_exit(NULL);
}

int main(int argc,char **argv)
{
    /*1. 创建子线程*/
    pthread_t thread_id;
    if(pthread_create(&thread_id,NULL,thread_work_func,NULL)!=0)
    {
        printf("子线程创建失败.\n");
        return -1;
    }
    /*2. 等待子线程结束-清理子线程的空间*/
    pthread_join(thread_id,NULL);//--wait
    printf("主线程正常终止.\n");
    return 0;
}

2. 如何接收子线程的返回值?

线程运行的时候默认是结合模式,也可以设置成分离模式,如果是默认的模式,在线程执行完毕后需要回收资源,顺便可以介绍子线程结束时,返回的状态值。

函数原型:

int pthread_join(pthread_t thread, void **retval);

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>

//[wbyq@wbyq linux_c]$ gcc app.c -lpthread

/*
线程工作函数
*/
void *thread_work_func(void *dev)
{
    int i;
    for(i=0;i<5;i++)
    {
        sleep(1);
        printf("子线程正在运行.%d \n",i);
    }
    //终止当前线程执行
    pthread_exit("1234567890");
}

int main(int argc,char **argv)
{
    /*1. 创建子线程*/
    pthread_t thread_id;
    if(pthread_create(&thread_id,NULL,thread_work_func,NULL)!=0)
    {
        printf("子线程创建失败.\n");
        return -1;
    }
    /*2. 等待子线程结束-清理子线程的空间*/
    char *p;
    pthread_join(thread_id,&p);//--wait
    printf("主线程正常终止.子线的返回值:%s\n",p);
    return 0;
}

3. 设置线程的分离属性

默认情况下,子线程是结合模式,需要手动等待子线程结束,清理空间;子线程也支持设置为分离属性,在子线程运行结束后,自己清理空间,下面的例子就演示如何设置子线程为分离模式。

函数原型:

int pthread_detach(pthread_t thread);

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>

//[wbyq@wbyq linux_c]$ gcc app.c -lpthread

/*
线程工作函数
*/
void *thread_work_func(void *dev)
{
    int i;
    for(i=0;i<5;i++)
    {
        sleep(1);
        printf("子线程正在运行.%d \n",i);
    }
    //终止当前线程执行
    pthread_exit(NULL);
}

int main(int argc,char **argv)
{
    /*1. 创建子线程*/
    pthread_t thread_id;
    if(pthread_create(&thread_id,NULL,thread_work_func,NULL)!=0)
    {
        printf("子线程创建失败.\n");
        return -1;
    }
    /*2. 设置线程的分离属性*/
    pthread_detach(thread_id);
    while(1)
    {
        printf("主线程正在运行.\n");
        sleep(1);
    }
    return 0;
}

4. 注册线程的清理函数

线程清理函数,可以在线程退出时自动调用或者手动调用,用于清理一些需要释放的资源。

函数原型:

//注册
void pthread_cleanup_push(void (*routine)(void *),void *arg); 
//释放
void pthread_cleanup_pop(int execute);

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
#include <pthread.h>

//[wbyq@wbyq linux_c]$ gcc app.c -lpthread

//线程的清理工作函数
void thread_clear_work_func(void *dev)
{
    printf("线程的清理工作函数被调用.\n");
    /*
    做一些资源清理工作。
    比如: 释放malloc申请的空间,关闭打开的文件等等.
    */
}

/*
线程工作函数
*/
void *thread_work_func(void *dev)
{
    int i;
    //注册清理函数
    pthread_cleanup_push(thread_clear_work_func,NULL); 
    for(i=0;i<5;i++)
    {
        sleep(1);
        printf("子线程正在运行.%d \n",i);
    }

    //终止当前线程执行
    pthread_exit(NULL);
    
    //释放清理函数
    pthread_cleanup_pop(1); 
}

int main(int argc,char **argv)
{
    /*1. 创建子线程*/
    pthread_t thread_id;
    if(pthread_create(&thread_id,NULL,thread_work_func,NULL)!=0)
    {
        printf("子线程创建失败.\n");
        return -1;
    }
    /*2. 设置线程的分离属性*/
    pthread_detach(thread_id);
    
    sleep(3);
    //取消指定子线程结束
    pthread_cancel(thread_id);

    while(1)
    {
        printf("主线程正在运行.\n");
        sleep(1);
    }
    return 0;
}

5. 通过ulimit命令设置栈空间大小

pthread_create 创建线程时,若不指定分配堆栈大小,系统会分配默认值,查看默认值方法如下:

[root@tiny4412 ]#ulimit -s
10240

上面的10240单位是KB,也就是默认的线程栈空间大小为10M

也可以通过ulimit -a命令查看,其中的stack size也表示栈空间大小。

[root@tiny4412 ]#ulimit -a
-f: file size (blocks)             unlimited
-t: cpu time (seconds)             unlimited
-d: data seg size (kb)             unlimited
-s: stack size (kb)                10240
-c: core file size (blocks)        0
-m: resident set size (kb)         unlimited
-l: locked memory (kb)             64
-p: processes                      7512
-n: file descriptors               1024
-v: address space (kb)             unlimited
-w: locks                          unlimited
-e: scheduling priority            0
-r: real-time priority             0

设置栈空间大小: ulimit -s <栈空间大小>

[root@tiny4412 ]#ulimit -s 8192   //设置栈空间大小
[root@tiny4412 ]#ulimit -s        //查看栈空间大小
8192                          //大小为8M

注意: 栈空间设置只能在超级管理员用户权限下设置。

每个线程的栈空间都是独立的,如果栈空间溢出程序会出现段错误。如果一个进程有10个线程,那么分配的栈空间大小就是10*<每个线程栈大小>

例如:

int main(int argc,char **argv)
{
    char buff[1024*1024*10];  //在栈空间定义数组,如果超出了栈空间总大小程序会奔溃。
    printf("hello world!\n");
    return 0;
}
目录
相关文章
|
9月前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
7月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
285 67
|
9月前
|
存储 Linux
linux中的目录操作函数
本文详细介绍了Linux系统编程中常用的目录操作函数,包括创建目录、删除目录、读取目录内容、遍历目录树以及获取和修改目录属性。这些函数是进行文件系统操作的基础,通过示例代码展示了其具体用法。希望本文能帮助您更好地理解和应用这些目录操作函数,提高系统编程的效率和能力。
353 26
|
9月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
178 26
|
9月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
186 17
|
2月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
420 2
二、Linux文本处理与文件操作核心命令
|
2月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
290 137
|
2月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
676 57
|
1月前
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
399 2
|
2月前
|
缓存 监控 Linux
Linux内存问题排查命令详解
Linux服务器卡顿?可能是内存问题。掌握free、vmstat、sar三大命令,快速排查内存使用情况。free查看实时内存,vmstat诊断系统整体性能瓶颈,sar实现长期监控,三者结合,高效定位并解决内存问题。
271 0
Linux内存问题排查命令详解

热门文章

最新文章