day29:零基础学嵌入式之线程1.0
一、线程的认识
1.为什么需要线程?
例如一个app服务器,需要同时创建超级多个任务来处理多个客户需求,如果创建进程,需要把进程的各个段全都复制一份,很占空间和时间。而线程的创建只需要线程id、程序计数器、寄存器、栈,其他资源共享本身的进程资源。所有。线程创建时,需要的资源非常少.创建效率高于进程,任务切换的时候速率也高于进程,所以创建效率更高于进程
2.什么是线程?
- 轻量级的进程;
(1)轻量级体现:
- 线程创建时,需要的资源非常少
- 创建效率高于进程
- 任务切换的时候速率也高于进程
3.线程与进程之间的关系:
- 线程时依附进程的(多个线程共享进程的资源;进程如果不存在,线程也不复存在);
- 一个进程中,可以有多个线程
- 一个进程中,如果只要一个线程被称为单线程进程
4.线程的组成部分:
(1)私有资源
- 线程id
- 程序计数器
- 一组相关的寄存器
- 栈
(2)共有部分
- 多个线程共享的进程资源
二、学习线程
补充:线程库的背景:由RedHat公司发布和创建,称NPTL线程库,提供了现成的创建、执行、结束、等相关函数接口,因为这是第三方库提供,所以要在编译的时候链接-pthread。
1.线程的生命周期
2.创建 pthread_create
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
(1)功能:创建一个新的线程
(2)参数
- thread---------线程id
- attr-------------线程的属性//NULL(默认属性:可结合性)
- start_routine---线程的回调函数//线程执行任务的函数
- arg-------------给线程的回调函数的参数
(3)返回值:
成功返回0;
失败返回errno(错误码);
(4)线程之间的关系
- 主线程所在的执行流-----主线程;其他线程-------子进程
- 所有线程关系是对等的(并发:同时创建),创建好之后,各个线程时并行的
(5)线程共享的进程空间的资源
- 全局变量 ---------- 线程间数据的共享
- 局部变量 ----------- 如果传进去局部变量的地址,并且在线程内进行修改,是共享的,如果是传进去,但是没有对地址进行修改,用一个线程内的局部变量,则是不共享的
- 堆区空间
示例代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>#include <stdlib.h>#include<string.h>void * do_something (void *agr)
{//static int status = 99;printf("---------%s-----",__FUNCTION__);// pthread_exit(&status);pthread_exit("hello");
}int main(int argc, char **argv)
{pthread_t tid1;int ret = pthread_create(&tid1, NULL, do_something, NULL);void *vel;pthread_join(tid1, &vel);// printf("vle is :%d \n",*(int *)vel);printf("vle is :%s \n",(char *)vel);return 0;
}
相关函数:pthread_self()
(1)功能:获得当前线程的tid;
(2)参数:void,空类型
(3)返回值:returning the calling thread's ID.
3.执行
(1)体现在线程的回调函数
4.退出
(1)线程的结束:一个新的线程结束,是下面的其中一种
- 调用pthread_exit(),pthread_exit与i出时可以指定一个退出状态值,这个值可以以被也同一进程中的另外一个线程使用,pthread_join【主动结束,带出状态值的地址】
- 线程结束,从线程回调函数中返回,这种也是线程的结束【主动结束,带出状态值的地址】
- pthread_cancel:线程可以被取消,类似kill【被动取消】
- 在这个进程中任意一个线程调用exit(),或者时程序从mian返回,结束的是进程,而进程结束,线程没有运行空间,就全部结束
补充:可结合(线程的属性):决定了线程资源回收的方式,这个线程结束时必须有其他线程进行pthread_join ----------- 手动回收
void pthread_exit(void *retval);【主动】
(1)功能:结束调用线程
(2)参数:retval:------带出的状态值,(void *)这里时状态值的地址
- 这个状态值,可以被统一进程中的另外一个线程获取,前提是,该线程,必须是可结合的县城属性
注意:
- 如果主线程调用pthread_exit此时效果是结束主线程的运行,并没有结束进程,进程会在其余所有线程结束之后才结束
int pthread_join(pthread_t thread, void **retval);
(1)功能:等待指定的线程退出,获得退出状态值
(2)参数:
- thread-----要等待的线程itid
- retval------获取退出的状态值
(3)返回值
成功返回0;
失败返回errno
示例代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>#include <stdlib.h>#include<string.h>void * do_something (void *agr)
{//static int status = 99;static char status[24] = "hello";printf("---------%s-----",__FUNCTION__);pthread_exit(&status);
}
int main(int argc, char **argv)
{pthread_t tid1;int ret = pthread_create(&tid1, NULL, do_something, NULL);void *vel;pthread_join(tid1, &vel);printf("vle is :%s \n",(char *)vel);return 0;
}
注意:
- pthread_exit(),带出来的实际时状态值的地址
- pthread_join() 获得时存放状态的值的空间地址
int pthread_cancel(pthread_t thread)
(1)功能:向指定线程发送“取消请求”。
(2)参数:指定线程的tid
(3)返回值:
成功返回0;
失败返回erron
int pthread_detach(pthread_t thgread)
(1)功能:把线程标记为“分离状态”,线程退出后系统自动回收其资源,无需其他线程再对其 pthread_join
(2)参数:线程tid
(3)返回值
成功返回0;
失败返回非0;
总结:
线程 | 进程 | |
创建 | pthread_create | fock |
退出 | pthread_exit、return、pthread_cancel、exit | exit |
资源回收 | pthread_join | wait |
time命令:运行程序的总共消耗的时间