线程(thread):在一个程序中的多个执行路线;一个进程内部的一个控制序列
为了调用线程的函数库,需定义宏_REENTRANT,在程序中包含头文件pthrea.h并在编译程序时需选用( _lpthread )来链接线程库。
一、线程和进程的区别:
1.进程是资源分配单位,线程是CPU调度单位;
2.线程的切换效率比进程的切换效率高
3.同一进程的线程之间共享数据交换空间和文件描述符。
线程的实现方式:1)用户级线程;2)内核级线程;3)混合线程
二、线程相关函数:
1.头文件:#include<pthread.h>
2.线程安全:
1)一个进程中所有线程共享数据&文件描述符
数据:全局变量 全局静态 局部静态变量 堆区数据
(栈:函数之间不共享,作用域不同)
2)进程中的多线程是并发运行的;多核处理器上线程可能是并行运行的
(区别:并发运行和并行运行)
2.1)strtok 不保证线程安全 多线程可对共享资源进行修改,造成结果的不确定性
2.2)strtok_t 保证线程安全 多线程的运行结果的确定性 特例:可重入函数
3)在一个多线程程序里,默认情况下,只有一个errno变量供所有线程共享。(errno变量用于获取某个函数失败后的错误信息)
为解决在一个线程准备获取刚才的错误时,该变量很容易被另一线程中的函数调用所改变的问题,需要使用被称为可重入的例程,可重入代码可以被多次调用而仍然正常工作,这些调用可以来自不同线程的调用,也可以是某种形式的嵌套调用。因此,代码中可重入部分通常只使用局部变量,这使得每次对该代码的调用都将获得它自己的唯一的一份数据副本。
4)编写多线程程序时,通过宏_REENTRANT来告诉编译器需用可重入功能,宏_REENTRANT定义必须位于程序中的任何#include语句之前。
它将为我们做3件事:
4.1)对部分函数重新定义其可安全重入的版本,但其函数名一般不会发生改变,只会在函数名后加_r字符串;
4.2)stdio.h中原来以宏的形式实现的一些函数将变成可安全重入的函数;
4.3)在errno.h中定义的变量errno将成为一个函数调用,它能够以一种多线程安全的方式获取真正的errno值。
三、信号量进行同步
1.有两组接口函数用于信号量:他们之间不能互换,函数调用不同
1)来自POSIX的实时扩展,用于线程;
2)系统V信号,常用于进程同步。
最简单信号量:二进制信号量,只有0和1取值;
2.用于线程的信号量函数
头文件:#include<semaphore.h>
四、用互斥量进行同步:
使用互斥量在多线程程序中实现同步访问,它允许程序员锁住某对象,使得每次只有一个线程访问它;为控制对关键代码的访问,必须在此段代码之前锁住一个互斥量,然后在操作完成后解锁它。
头文件:#include<pthread.h>
未完待续…