您当前的位置: 首页 >  linux

风间琉璃•

暂无认证

  • 0浏览

    0关注

    337博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Linux之并发竞争管理

风间琉璃• 发布时间:2022-09-06 09:34:07 ,浏览量:0

Linux 系统是个多任务操作系统,会存在多个任务同时访问同一片内存区域,这些任务可能会相互覆盖这段内存中的数据,造成内存数据混乱。我们需要对共享数据进行相应的保护处理。

产生并发的主要原因有:

①多线程并发访问, Linux 是多任务(线程)的系统,多线程访问是最基本的原因

②抢占式并发访问,Linux 内核支持抢占,调度程序可以在任意时刻抢占正在运行的线程,从而运行其他的线程。

③中断程序并发访问,硬件中断的权利可以是很大的。

④SMP(多核)核间并发访问,多核 CPU 存在核间并发访问。

并发:多个执行单元同时进行或多个执行单元微观串行执行,宏观并行执行。微观串行,宏观并行:理解成把时间轴放大以后,各个任务是串行执行,然后每个任务执行一定的时间片,执行完后由调度系统调度到另一个任务去执行。因为CPU的速度很快,所以宏观看来是并行执行。 

竞争:并发的执行单元对共享资源(硬件资源和软件上的全局变量)的访问而导致的竞争状态。

临界资源: 多个进程访问的资源,共享数据段

临界区:多个进程访问的代码段

  一、原子操作

原子操作是指不能再进一步分割的操作。一般原子操作用于整形变量或者位操作。

Linux 内核定义了叫做 atomic_t 的结构体来完成整形数据的原子操作,在使用中用原子变量来代替整形变量,此结构体定义在 include/linux/types.h 文件中

typedef struct {
    int counter;
} atomic_t;

如果要使用原子操作 API 函数,首先要先定义一个 atomic_t 的变量,

atomic_t a; //定义 a
atomic_t b = ATOMIC_INIT(0); //定义原子变量 b 并赋初值为 0

原子变量有了,接下来就是对原子变量进行操作,读、写、增加、减少。

原子操作API函数

 如果使用 64 位的 SOC 的话,就使用64 位的原子变量

typedef struct {
    long long counter;
} atomic64_t;

 相应的操作函数把“atomic_”前缀换为“atomic64_”,将 int 换为 long long即可。

原子位操作:即位操作,在Linux 内核也提供了一系列的原子位操作 API 函数,原子位操作不像原子整形变量那样有个 atomic_t 的数据结构,原子位操作是直接对内存进行操作。

 

atomic_t lock;			/* 原子变量 */

/* 初始化原子变量 */
atomic_set(&lock, 1);	/* 原子变量初始值为1 */

atomic_inc(&lock); /*释放原子变量*/


/* 通过判断原子变量的值来检查共享资源有没有被别的应用使用:1 */
//若为1 则1-1为0 ,返回真,取反为假
//若为0 ,则0-1不为0,返回假,取反为真,执行下面
if (!atomic_dec_and_test(&gpioled.lock)) {
	atomic_inc(&gpioled.lock);	/* 小于0的话就加1,使其原子变量等于0 */
	return -EBUSY;				/* 共享资源被使用,返回忙 */
}



/* 通过判断原子变量的值来检查共享资源有没有被别的应用使用:2 */
if(atomic_read(&lock)             
关注
打赏
1665385461
查看更多评论
0.0572s