Linux 多线程:线程安全之同步与互斥的理解

Posted 爱喝酸奶!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux 多线程:线程安全之同步与互斥的理解相关的知识,希望对你有一定的参考价值。

目录


  在看线程安全之前要明白临界资源的概念。 临界资源就是一次只允许一个进程使用的资源。就像厕所一样,一次只能一个人用。因此需要 合理控制对于临界资源的访问操作,使得程序可以正常运行,这就是线程安全。

  线程安全分为两部分:同步与互斥

一、对互斥的理解

互斥是什么?

  互斥是为了保证程序运行的安全性。一个程序在使用临界资源时,其他线程就不可以使用,只有等到其他线程使用完毕才可以去使用。就像厕所一样,只有一个人用完了,第二个人才可以进去,不然只能在外面等。

如何实现互斥?

 (1)通常使用互斥锁来实现线程的互斥。这个互斥锁其实就是一个0/1计数器,0代表临界资源正在被使用,1代表临界资源是空闲的。

 (2)如果A线程要访问临界资源,此时就去看一下互斥锁是不是已经被锁上了,如果被锁上说明这个临界资源正在被使用。如果临界资源没有被锁上,说明此时临界资源是空闲的,A线程可以去使用。使用前A线程需要给临界资源加锁,A线程加的锁只有自己才可以打开锁,其他线程是打不开的。

 (3)这就像是A去上厕所,然后把门反锁,这样其他人就进不去,也打不开锁,只有A自己才可以把锁打开。所以说互斥锁其实和现实中的锁是很像的。

 (4)访问临界资源的时候,如果可以访问则加锁,将资源标记为不可访问状态,然后正确返回。如果资源此时不可以访问,那么就会阻塞或者报错返回。

 (5)要实现互斥的话,最重要的是大家必须使用同一把锁。就像自己家的门,家里人都有钥匙,但是锁只有一把。如果一人一把锁,那就乱套了。因此这也证明了互斥锁也是一个临界资源,因此对互斥锁的操作一定要保证是安全的。

二、对同步的理解

同步是什么?

  同步是为了保证程序运行的合理性。如果有多个线程都要访问同一个临界资源,那么肯定要规划好谁先谁后的问题,不然一窝蜂地跑去使用临界资源很容易出问题。如果好几个人要使用厕所,但厕所只有一个,这个时候就要排个队,让所有人都能合理的使用厕所,不至于让几个人去抢厕所。

如何实现同步?

 (1)同步就是让访问资源变得更加合理。比如:实现互斥时,为了让资源访问变得安全,我们在访问前给资源加锁,访问后解锁。但是什么时候加锁,什么时候解锁,如何把握这个时间点,就是同步的问题了。

 (2)而我们使用条件变量来进行同步,条件变量里面包含了许多的工具,我们需要做的事情就是规定什么时候去使用什么工具来保证资源访问的合理性

Linux多线程同步之互斥量和条件变量

1. 什么是互斥量

       互斥量从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁以后,任何其他试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所以在该互斥锁上的阻塞线程都会变成可进行状态,第一个变成运行状态的线程可以对互斥量加锁,其他线程在次被阻塞,等待下次运行状态。

pthread_mutex_t 就是POSIX对于mutex的实现。

函数名 参数 说明
pthread_mutex_init

pthread_mutex_t * mutex,

constpthread_mutex_t *attr
初始化一个互斥量,静态方式可以直接使用PTHREAD_MUTEX_INITIALIZER进行赋值初始化
pthread_mutex_destroy pthread_mutex_t *mutex 释放对互斥变量分配的资源。注意pthread_mutex_init有可能malloc了资源
pthread_mutex_lock pthread_mutex_t *mutex 如果互斥量已经上锁,调用线程阻塞直至互斥量解锁
pthread_mutex_trylock pthread_mutex_t *mutex 加锁,如果失败不阻塞
pthread_mutex_unlock pthread_mutex_t *mutex 解锁
使用init函数进行初始化: