嵌入式开发学习日志(linux系统编程--进程(3)——线程)Day29

发布于:2025-05-28 ⋅ 阅读:(24) ⋅ 点赞:(0)

Linux命令的补充

1、

一、线程

概念

1、线程是轻量级进程,一般是一个进程中的多个任务。

           2、进程是系统中最小的资源分配单位;

                线程是系统中最小的执行单位。

特征


1、共享资源:

2、效率高 30%

3、三方库: pthread clone posix

4.、编写代码头文件: pthread.h

5、 编译代码加载库: gcc x.c -lpthread

扩:以lib开头 .so结尾的为动态库(在内核中),中间的pthread为库名。

优缺点

优点:比多进程节省资源,可以共享变量。

缺点:1.线程和进程相比,稳定性,稍微差些

          2.线程的调试gdb,相对麻烦些,因为并发

二、线程与进程的区别(面问)


1、资源:

(1)线程比进程多了共享资源;

(2)线程又具有部分私有资源;

(3)进程间只有私有资源没有共享资源。

2、空间:

(1)进程空间独立(写时复制),不能直接通信;

(2)线程可以共享空间(栈区默认不共享),可以直接通信。

3、不同点:

(1)创建开销不一样,进程创建需要3G空间,线程创建只需要8M,线程并发度高于进

        程;

(2)进程变量不共享;

(3)进程切换(复杂)需要的缓存空间多,线程切换栈区,PC指针也发生变化;

(4)进程可申请到硬件资源;

4、稳定性差异:

(1)线程稳定性差(其中一个线程崩溃或严重异常,进程直接结束);

(2)项目任务复杂,用进程做;简单小任务,用线程做;

5、共同点:都能并发。

6、考虑用线程还是进程的两个准则:

(1)稳定性;

(2)看资源够不够用(够用用线程)

三、多线程程序设计步骤


1、创建多线程(只要创建成功就启动了)

2、线程空间操作 (设计函数表达要干什么)

3、线程资源回收(栈区回收,默认进程结束栈区不释放)

注:

(1)进程中的第一个线程为主线程,主线程有且仅有一个,(主线程号和进程号一

致)其它次线程为平级关系;

(2)主线程不需创建,运行a.out就出来了,后调用函数创建其他空间,在进程空间新

开栈区(8M)。

四、关于线程的函数

        创建多线程 ==》线程空间操作 ===》线程资源回收

1、创建多线程(pthread_create)


形式:
        int pthread_create(pthread_t *thread,       const pthread_attr_t *attr,     void *(*start_routine) (void *),       void *arg);
功能:
    该函数可以创建一个指定的线程;
参数:
【pthread_t *thread】:线程pid号(新线程的线程号    )
【const pthread_attr_t *attr】:线程的属性,默认常规NULL,
【void *(*start_routine) (void *)】:函数的名字,空类型,空参数的(回调函数)是线程的执行空间
【void *arg】:参数,(线程工作的时候需要外部传参时,如果不需要,传NULL)

返回值:成功 0;
              失败 错误码;

eg:

 注意:(1)一次pthread_create执行只能创建一个线程。
            (2)每个进程至少有一个线程称为主线程。
            (3)主线程退出则所有创建的子线程都退出。 
            (4)主线程必须有子线程同时运行才算多线程程序。
            (5) 线程id是线程的唯一标识,是CPU维护的一组数字。
            (6)pstree 查看系统中多线程的对应关系。
            (7)多个子线程可以执行同一回调函数。
            (8)  ps -eLf 查看线程相关信息Low Weigth Process
            (9)  ps -eLo pid,ppid,lwp,stat,comm

2、获取线程号(pthread_self)

形式:

                        pthread_t    pthread_self(void);

功能:

        获取当前线程的线程id;

返回值:

        成功 返回当前线程的线程id,返回值为unsigned long int类型; %lu
                 失败  -1;

 3、strerror

形式:

                char *strerror(int errnum);

功能:

(1)报错函数,用于线程报错(多为极端情况使用),也可调用perror()函数(大部分

        情况使用)

(2)strerror(errno)中errno为错误码

eg:

4、线程的退出pthread_exit

形式:

                 void pthread_exit(void *retval);

参数:

        若没有返回的值,则传NULL;

        线程退出时候的返回状态,临死遗言。

功能:

        自行退出==》自杀===》子线程自己退出

        子线程自己退出;

等价关系:

pthread_exit(NULL);

return (NULL);

 eg:

 5、线程的退出pthread_cancel;

形式

        int pthread_cancel(pthread_t thread);

 参数:

        【pthread_t thread】:将要结束的子线程线程号;

功能:

        强制退出===》他杀====》主线程结束子线程;

返回值:

                成功 0
                失败 -1

 注意:

        只能是主线程去结束子线程;

eg:

五、线程的回收

线程的回收机制  ====》不同与进程没有孤儿线程和僵尸线程。
                           ====》主线程结束任意生成的子线程都会结束。
                           ====》子线程的结束不会影响主线程的运行。

关于线程的回收的函数

1、pthread_join

形式:

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

参数:

        【pthread_t thread】:回收线程的ID号;

        【void **retval】:要回收的子线程返回值/状态。==》ptread_exit(值);

功能:

        通过该函数的可以将指定的线程资源回收,该函数具有阻塞等待功能,如果指定的线程未结束,则回收的线程会阻塞;

返回值:

            成功 0
            失败 -1;

子线程的回收策略:
  1、如果预估子线程可以有限范围内结束则正常用pthread_join等待回收。
  2、如果预估子线程可能休眠或者阻塞则等待一定时间后强制回收。
  3、如果子线程已知必须长时间运行,则不再回收其资源。

eg:(1)用函数pthread_join不传参

(2)用函数pthread_join传参

六、设置分离属性

目的:线程消亡,自动回收空间。

1、pthread_attr_init()


(1)函数原型:int pthread_attr_init(pthread_attr_t *attr);

(2)功能:初始化一个attr的变量

(3)参数:attr,需要变量来接受初始值

(4)返回值:0 成功,非0 错误

2、pthread_attr_destroy()


(1)函数原型:int pthread_attr_destroy(pthread_attr_t *attr);

(2)功能:销毁attr变量

(3)参数:attr,属性变量

(4)返回值:0 成功,非0 错误

3、pthread_attr_setdetachstate()


(1)函数原型: int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);

(2)功能:把一个线程设置成相应的属性

(3)参数:attr,属性变量,有init函数初始化他。
                    detachstate:有2个可选值,
                    PTHREAD_CREATE_DETACHED

4、pthread_deatch()

(1)函数原型:int pthread_deatch(pthread_t thread);

(2)功能:设置分离属性

(3)参数:线程id号,填自己的id线程清理函数

                        如果在主线程中,则使用子线程的id号


5、pthread_cleanup_push()


(1)函数原型:void pthread_cleanup_push(void (*routine)(void *), void *arg);

(2)功能:注册一个线程清理函数

(3)参数:routine,线程清理函数的入口
                    arg,清理函数的参数。

(4)返回值:无

6、pthread_cleanup_pop()


(1)函数原型:void pthread_cleanup_pop(int execute);

(2)功能:调用清理函数

(3)参数:execute,非0 执行清理函数
                                     0 ,不执行清理

(4)返回值:无

注:pthread_cleanup_push与pthread_cleanup_pop函数需成对出现;

 练习:

1、验证线程的变量是共享的;全局变量;

2、//验证线程的变量是共享的;

 3、用结构体进行传参;


网站公告

今日签到

点亮在社区的每一天
去签到