多线程编程(1)

线程概念


线程线程就是进程的若干个执行流,

因为一个进程在某一时刻只能去做一件事情,有了线程之后,我们可以在同一时间去做不同的事情,比如我正在边利用cmd markdown写博客。边用网易云音乐听音乐,这样多线程的情况下,能给我们带来很多好处。

进程

多线程

在系统内核中其实是不存在线程的,linux使用进程模拟线程,线程的实现其实就是多个共享数据代码等信息的进程。所以我们把线程也叫做轻量级进程。

进程常常用来分配资源,线程用来调度资源。

线程中共享的资源:
- 文件描述符表
- 信号处理方式
- 当前工作目录
- uid,gid

线程中独立的资源:
- 线程id(tid)
- 线程的上下文信息,寄存器信息,PC制作,栈指针
- 栈空间
- errno变量
- 信号屏蔽字
- 调度优先级
- 线程私有数据

线程的函数大部分都放在pthread.h的头文件当中,并且在编译的时候我们需要注意的是加上-lpthread选项,这样就会去动态链接动态库。

线程控制


线程的控制

  • 创建线程
    线程的创建使用线程创建函数。
  int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

需要注意的是线程创建函数的参数,第三个参数start_rountine就是新创建的线程所要跑的函数,arg是你传入的参数。

因为在linux环境下,系统内部其实是不存在线程的,我们一般说线程叫做轻量级进程,线程创建以后,两个线程的pid和ppid都是一样的。操作系统会为之提供一个线程的tid,这个tid我们可以通过一个函数获取:

 pthread_t pthread_self(void);

需要注意的是pthread_self所获取到的是相对于进程的线程控制块的首地址,只是用来描述统一进程当中的不同的线程。而真正的内核当中的线程ID,对于多线程进程来说,每个tid实际是不一样的。

另外,在linux当中如果你要查询系统中的线程,也有一条命令:ps -aL

  • 线程等待
    在进程当中我们提到过,如果我们当子进程结束以后,这个时候需要让父进程得到信息,然后由父进程去进行资源的回收,以及后续的处理,所以我们要确保子进程先结束,然后父进程再结束,否则会出现僵死状态,当值内存泄漏的问题。所以进程当中我们提到了wait和waitpid函数。
    线程当中同样有上述的问题,当你的新线程结束,你的主线程也是需要等待,然后回收新线程的资源及其他信息。这样就能确保内存不泄露。所以这里使用一个函数pthread_join函数来进行等待。
int pthread_join(pthread_t thread, void **retval);

thread就是线程号,retval是一个二级指针,用途是用来获取线程的退出码。

  • 终止线程
    线程可以等待,当然也可以终止。终止线程可以使用三种方法:
方法
1 使用return返回,在主线程当中执行的时候类似于exit,直接结束进程
2 使用pthread_exit函数,终止自己的线程
3 使用pthread_cancel函数,可以用来终止统一进程的线程
void pthread_exit(void *retval);

pthread_exit用来终止线程自身,参数是返回的错误码,想要获得这个错误码,可以通过pthread_join来获得。

int pthread_cancel(pthread_t thread);

pthread_cancel参数为要终止线程的tid,

分离线程和结合线程


线程是可结合或者是分离的。
一个可结合的新线程需要被主线程回收资源和杀死。一个可结合的线程会容易出现类似于僵尸进程的问题,一般我们采用join来等待。否则就会出现主线程无法获取到新线程信息,无法回收新线程的资源,这样就会造成内存泄漏的问题。我们在默认的情况下,线程是可结合的。<

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值