原子操作,自旋锁,信号量,互斥体

一:原子操作
  原子操作是操作的最小单位不再可分,也就是在这个操作的过程中不会被其他进程(包括中断)打断,直至这个原子操作执行完。表面上i++是原子操作,实际上i++这个C语言语句被翻译成汇编语句是有好几条的,如果在执行的过程中被打断,那么就会导致计数出错。在多进程中如果多个进程都会访问同一个数据段恰好这个数据段内有对数据的操作,那么如果A进程正在对这个数据进行操作的过程,B进程被调度到cpu执行也恰好对这个数据进行操作,那么就会出现问题。最经典的例子就是多线程计数的例子。

原子操作,自旋锁,信号量,互斥体_第1张图片

二:自旋锁
  临界区指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段。临界区需要被保护,在运行到临界区前面的时候马上上锁,退出临界区的时候解锁,自旋锁要用在上锁时间短的情况下。

三:信号量
  Linux中的信号量是一种睡眠锁,如果有一个任务试图获得一个不可用(已经被占用)的信号量时,信号量会将这个任务推进一个等待队列,然后让其睡眠(CPU不再调度它,和自旋锁不同)。这时候处理器能够重新获得自由,从而去执行其他代码。当持有的信号量可用(被释放)后,处于等待队列中的那个任务就将被唤醒,并获得该信号量。
  信号量分为计数信号量和二值信号量(互斥信号量)。信号量可以同时允许任意数量的锁持有者,而自旋锁在一个时刻最多允许一个任务持有它。
  使用信号量的时候有down_interruptible和down。当信号量来没来时(信号量没被释放),down和down_interruptible都进入睡眠等待状态但是down_interruptible进入的是TASK_INTERRUPTIBLE状态,down进入的是TASK_UNINTERRUPTIBLE状态,down_interruptible可以接收SIGINT信号从而从睡眠等待状态中唤醒继续运行,而down不可以接收SIGINT信号,从而不能从睡眠等待状态中唤醒继续运行,必须等到信号量来了才能继续运行。

四:互斥体
  在 FreeRTOS和 UCOS中也有互斥体,将信号量的值设置为 1就可以使用信号量进行互斥
访问了,虽然可以通过信号量实现互斥,但是 Linux提供了一个比信号量更专业的机制来进行
互斥,它就是互斥体 mutex。互斥访问表示一次只有一个线程可以访问共享资源,不能递归申
请互斥体。在我们编写 Linux驱动的时候遇到需要互斥访问的地方建议使用 mutex。 Linux内核使用
mutex结构体表示互斥体。
原子操作,自旋锁,信号量,互斥体_第2张图片

你可能感兴趣的:(多线程,编程语言,linux)