线程安全与可重入函数的联系与区别

轻量级进程(LWP)是计算机操作系统中一种实现多任务的方法。

计算机操作系统中,轻量级进程(LWP)是一种实现多任务的方法。与普通进程相比,LWP与其他进程共享所有(或大部分)它的逻辑地址空间和系统资源;与线程相比,LWP有它自己的进程标识符,优先级,状态,以及栈和局部存储区,并和其他进程有着父子关系;这是和类Unix操作系统的系统调用vfork()生成的进程一样的。另外,线程既可由应用程序管理,又可由内核管理,而LWP只能由内核管理并像普通进程一样被调度。Linux内核是支持LWP的典型例子。

在大多数系统中,LWP与普通进程的区别也在于它只有一个最小的执行上下文和调度程序所需的统计信息,而这也是它之所以被称为轻量级的原因。一般来说,一个进程代表程序的一个实例,而LWP代表程序的执行线程(其实,在内核不支持线程的时候,LWP可以很方便地提供线程的实现)。因为一个执行线程不像进程那样需要那么多状态信息,所以LWP也不带有这样的信息。

LWP的一个重要作用是提供了一个用户级线程实现的中间系统。LWP可以通过系统调用获得内核提供的服务,因此,当一个用户级线程运行时,只需要将它连接到一个LWP上便可以具有内核支持线程的所有属性。

各线程还共享以下进程资源和环境:
1. 文件描述符表
2. 每种信号的处理方式(SIG_IGNSIG_DFL或者自定义的信号处理函数)
3. 当前工作目录
4. 用id和组id

但有些资源是每个线程各有一份:
1. 线程id
2. 上下文,包括各种寄存器的值、程序计数器和栈指针
3. 栈空间
4. errno变量
5. 信号屏蔽字
6. 调度优先级

进程强调独占,而线程强调共享。线程私有最重要的是:硬件上下文,栈帧。

多个线程看见公共资源,如果不保护,则会发生异常,线程安全(一个线程修改会影响另一个线程执行逻辑异常)。

产生线程安全本质:线程共享资源,造成一定影响。

同一个进程内部另一个执行流:信号处理

线程安全:

       线程安全函数:在C语言中局部变量是在栈中分配的,任何未使用静态数据或其他共享资源的函数都是线程安全的。而使用全局变量的函数是非线程安全的。
       使用静态数据或其他共享资源的函数,必须通过加锁的方式来使函数实现线程安全。

       线程安全的:
                   如果一个函数在同一时刻可以被多个线程安全地调用,就称该函数是线程安全的。
                   线程安全函数解决多个线程调用函数时访问共享资源的冲突问题。

可重入:

  1. 函数被不同的控制流程调用,有可能在第一次调用还没返回时就再次进入该函 数,这称为重入。

  2. 访问时有可能因为重入而造成错乱,像这样的函数称为 不可重入函数,反之,如果一个函数只访问自己的局部变量或参数,则称为可重入函数。

3..可重入函数特点: 函数可以由多于一个线程并发使用,而不必担心数据错误。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重 入性解决函数运行结果的确定性和可重复性。 所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。

可重入函数编写规范为:

1、不在函数内部使用静态或全局数据 
2、不返回静态或全局数据,所有数据都由函数的调用者提供。 
3、使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。
4、如果必须访问全局变量,利用互斥机制来保护全局变量。
5、不调用不可重入函数。

两者之间的关系:
1、一个函数对于多个线程是可重入的,则这个函数是线程安全的。
2、一个函数是线程安全的,但并不一定是可重入的。【使用互斥锁实现的线程安全】
3、可重入性要强于线程安全性。

注:可重入函数是指函数内部没有使用共享变量。可重入函数是线程安全函数的一个真子集。

C语言:可重入函数是说当一个函数被不同的线程同时访问的时候,每一个调用都独自使用自己的一份数据,多次调用之间不存在数据共享。所以说C语言可重入的函数一定是线程安全的,因为根本就不存在多个线程共享一份数据问题,就不会发生访问冲突。可重入函数的要求是函数不访问全局或静态变量。

线程安全如果多个线程对同一个函数的多次调用之间存在共享数据,所有对共享数据的访问都必须是序列化的,每个线程按先来后到排队访问,也就是不存在同时访问。

C++中:类的成员函数可重入是说:类的成员函数在被多个线程在不同实例里面访问(每个线程一个实例)时,不存在共享数据,也不会有数据冲突。

类的可重入表示类的所有成员函数都是可重入的。
类的线程安全是说:类的同一个实例被多个线程访问的时候,对数据的操纵是序列化的,不会有访问冲突。

两者之间的区别:

1.可重入概念只和函数访问的变量类型有关,和是否使用锁没有关系。
2.而线程安全和锁的使用关系密切,很多时候线程安全是靠锁来保证的。

你可能感兴趣的:(线程安全,可重入)