一、进程线程关系
1、首先,Linux中并不存在真正意义上的线程,是通过pthread库加载到相应进程的地址空间之中,在共享区里存储着轻量级进程------也就是用户态线程的信息,其中有栈区等等。各个线程之间有独自的栈区空间,但是堆区公用。
2、进程是资源分配的基本单位,线程是cpu调度的基本单位。cpu并不拥有系统资源,而是共享进程申请来的系统资源;线程不具有自己的地址空间,而是共享进程申请来的地址空间,只不过在则个地址空间中拥有自己独立的一小部分;线程不包含cpu现场,不能独立执行程序;线程之间大多共享,少量独占,所以线程之间的通信比进程编程简单,但是这也带来了线程安全的问题,以及多线程环境在因为共享同一个地址空间,所以在访问公共变量或内存时需要引入同步机制
3、用户态线程的切换在用户态实现,不需要内核的支持。线程和进程都可以并发执行,但是线程之间有大量资源共享,粒度更小占用资源更少,所以并发执行的可行性比进程更高,不过这意味着安全性的降低,因为一个线程退出,会导致同一个进程中的所有线程和进程都推出;对于大量的计算操作,应该使用多线程,以发挥现在大部分机器的多cpu优势,能够提高机器的程序响应速度
4、程序是一个静态的东西,只有在程序运行的时候,才存在进程这个实体概念,是一次程序的运行,因此说一个程序只有至少有一个进程,是错误的;一个线程可以创建和撤销另一个线程;在多进程环境下,子进程可以复制父进程堆栈中的所有的数据,但是线程之间则会共享除了自己的寄存器和栈,为通信创建了良好条件
二、LWP理解
Light Weight Process轻量级进程,是通过pcb实现的,这个pdb有自己的pid,与创建它的进程共用同一块地址空间,所以相对创建的时间、空间成本低;而我们用户调用pthread_create创建的线程被成为用户级线程,是通过轻量级线程实现的,一个进程中所有的轻量级进程在一起组成一个线程组,这个线程组有自己的线程组ID,也就是进程的ID
三、线程互斥
1、锁:锁实际上就是一个计数器,比如说互斥锁就是0/1,如果是0就说明已经加锁成功,已经有一个线程在访问临界区资源,而如果是1,就说明现在没有线程在访问临界区资源,此时锁是可供获得的
2、所谓线程互斥,就是为了防止造成数据二义,所以共享区资源同一时间段内只能有一个线程访问
四、条件变量
条件变量提供了一个pcb阻塞队列,以及阻塞和唤醒线程的接口用于同步(pthread_cond_wait(cond, mutex), pthread_cond_signal(cond)),但是什么时候该唤醒或者该阻塞线程有程序员自己控制,条件变量需要搭配互斥锁使用,而信号量可以单独使用来实现线程的同步与互斥(二元信号量可以认为是一把互斥锁)。
条件变量在等待被唤醒时需要重新对条件进行判断,以避免线程被唤醒后在没抢到锁时阻塞,在抢到锁后访问时不满足访问条件,所以需要进行二次判断。具体实现方法可以通过while循环进行二次判断