3692|1

7172

帖子

195

TA的资源

五彩晶圆(高级)

楼主
 

《原子嵌入式Linux驱动开发详解与实战》第9章并发与竞争学习 [复制链接]

本帖最后由 常见泽1 于 2024-4-13 14:58 编辑

第八章第九章 LINUX并发与竞争学习心得

 

一原子操作

原子(atomic)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为“不可被中断的一个或一系列操作”,可以保证指令以原子的方式运行,即执行过程不被打断,如果被中断则可能会引起执行结果和预期不符。

 

 

atomic_read(atomic_t * v); 
该函数对原子类型的变量进行原子读操作,它返回原子类型的变量v的值。  

atomic_set(atomic_t * v, int i); 
该函数设置原子类型的变量v的值为i。  

void atomic_add(int i, atomic_t *v); 
该函数给原子类型的变量v增加值i。  

atomic_sub(int i, atomic_t *v); 
该函数从原子类型的变量v中减去i。  

int atomic_sub_and_test(int i, atomic_t *v); 
该函数从原子类型的变量v中减去i,并判断结果是否为0,如果为0,返回真,否则返回假。  

void atomic_inc(atomic_t *v); 
该函数对原子类型变量v原子地增加1。  

void atomic_dec(atomic_t *v); 
该函数对原子类型的变量v原子地减1。  

int atomic_dec_and_test(atomic_t *v); 
该函数对原子类型的变量v原子地减1,并判断结果是否为0,如果为0,返回真,否则返回假。  

int atomic_inc_and_test(atomic_t *v); 
该函数对原子类型的变量v原子地增加1,并判断结果是否为0,如果为0,返回真,否则返回假。  

int atomic_add_negative(int i, atomic_t *v); 
该函数对原子类型的变量v原子地增加I,并判断结果是否为负数,如果是,返回真,否则返回假。  

int atomic_add_return(int i, atomic_t *v); 
该函数对原子类型的变量v原子地增加i,并且返回指向v的指针。  

int atomic_sub_return(int i, atomic_t *v); 
该函数从原子类型的变量v中减去i,并且返回指向v的指针。  

int atomic_inc_return(atomic_t * v); 
该函数对原子类型的变量v原子地增加1并且返回指向v的指针。  

int atomic_dec_return(atomic_t * v); 
该函数对原子类型的变量v原子地减1并且返回指向v的指针。  

 

二自旋锁

原子操作只能对整型变量或者位进行保护,但是在实际的使用环境中不可能只有整形变量或位知名简单的临界区。

自旋锁的自旋就是原地打转的意思,原地打转的目的是等待自旋锁可以用,可以访问共享资源。

缺点:

等待自旋锁的线程会一直处于自旋状态,这样会浪费处理器时间,降低系统性能,所以自旋锁的持有时间不能太长。因此自旋锁适用于短时间的轻量级加锁。

 

 自旋锁为互斥设备,只有上锁与解锁两种状态

自旋锁示例:

 

 

测试例程:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <pthread.h>

//#include<vector>



pthread_spinlock_t spin_lock;

char num = 0;



void xprintf(char *str)

{

         int i = 0;

         while(str[i] != '\0')

         {

                   printf("%c", str[i++]);

                   fflush(stdout);

                   sleep(1);

         }

         return NULL;

}



void *producer(void *arg)

{

         int times = 1000000;       

         while(times--)

         {

         pthread_spin_lock(&spin_lock);

         num+=1;

printf("%d",num);

         pthread_spin_unlock(&spin_lock);

         }

}

void *comsumer(void *arg)

{

        int times = 1000000;

        while(times--)

        {

         pthread_spin_lock(&spin_lock);

        num-=1;

printf("%d",num);

        pthread_spin_unlock(&spin_lock);

        }

}



int main()

{

         pthread_spin_init(&spin_lock,0);

         pthread_t thread1,thread2;

         pthread_create(&thread1,NULL,producer,NULL);

         pthread_create(&thread2,NULL,comsumer,NULL);

         pthread_join(thread1,NULL);

         pthread_join(thread2,NULL);

         printf("%d",num);

return 0;

}

 

三信号量

 

信号量这个概念在ucos等单片机的微型操作系统里其实就已经有学过,算是有些相似吧,但是还是有区别的

信号量的特点:

1信号量可以使等待资源现成进入休眠状态,因此适用于那些占用资源比较久的场合

2信号量不能用于终端中,因为信号量会引起休眠, 中断不能休眠

3如果共享资源的持有时间比较短,那就不适合使用信号量了,因为频繁的休眠、切换现成引起的开销要远大于信号量带来的那点优势


#include <stdio.h>

#include <pthread.h>

#include <semaphore.h>

#include <unistd.h>



sem_t sem;



void xprintf(char *str)

{

         int i = 0;

         while(str[i] != '\0')

         {

                   printf("%c", str[i++]);

                   fflush(stdout);

                   sleep(1);

         }

         return NULL;

}



void *task_fun1(void *arg)

{

         sem_wait(&sem);

         xprintf((char *)arg);

         sem_post(&sem);

         return NULL;

}



void *task_fun2(void *arg)

{

         sem_wait(&sem);

        

         xprintf((char *)arg);



         sem_post(&sem);

        

         return NULL;

}





int main(int argc, char const *argv[])

{



         sem_init(&sem, 0, 1);

        

         pthread_t pthid1, pthid2;

        

         pthread_create(&pthid1, NULL, task_fun1, "TASK1");

         pthread_create(&pthid2, NULL, task_fun2, "TASK2");



         pthread_join(pthid1, NULL);

         pthread_join(pthid2, NULL);



        

         sem_destroy(&sem);

        

         return 0;

}

 

这里用到了多线程,所以要加 -pthread

gcc sem_thread.c -lpthread

实操进行测试

 

最新回复

支持一下楼主,辛苦了,感谢楼主分享的嵌入式Linux驱动开发的技术内容,希望楼主再接再厉   详情 回复 发表于 2024-10-1 12:29
点赞 关注

回复
举报

419

帖子

0

TA的资源

禁止发言

沙发
 

支持一下楼主,辛苦了,感谢楼主分享的嵌入式Linux驱动开发的技术内容,希望楼主再接再厉

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表