庆科社区
直播中

gjianw217

10年用户 688经验值
擅长:嵌入式技术 控制/MCU RF/无线
私信 关注

【MiCOKit试用体验】庆科MiCO系统篇(3)MiCO RTOS互斥锁

本帖最后由 gjianw217 于 2015-10-25 15:45 编辑

      在本帖子中,主要分析一下庆科MiCO RTOS的互斥锁,具体包括:
     OS互斥锁
     MiCO互斥锁关键API
     MiCO互斥锁示例
     MiCO互斥锁测试结果


一、OS互斥锁
     上篇分析了信号量,而互斥锁,是一种特殊的信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源。可以保证以下三点:
原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一个线程锁定了一个互斥量,没有其他线程在同一时间可以成功锁定这个互斥量。
唯一性:如果一个线程锁定了一个互斥量,在它解除锁定之前,没有其他线程可以锁定这个互斥量。
非繁忙等待:如果一个线程已经锁定了一个互斥量,第二个线程又试图去锁定这个互斥量,则第二个线程将被挂起(不占用任何cpu资源),直到第一个线程解除对这个互斥量的锁定为止,第二个线程则被唤醒并继续执行,同时锁定这个互斥量。
      从以上三点,我们看出可以用互斥量来保证对变量(关键的代码段)的排他性访问。即信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用。
二、MiCO 互斥锁关键API

       在MiCO中,对于互斥锁的定义,位于SDK_MiCOKit_v2.3.0.2includemico_rtos.h中,主要有以下函数:
2.png
其中,常用的有:

(1)OSStatus mico_rtos_init_mutex(mico_mutex_t* mutex );
该函数为初始化一个互斥锁,参数为指向要初始化的互斥锁的句柄的指针(typedef void* mico_mutex_t;)
(2)OSStatus mico_rtos_lock_mutex(mico_mutex_t* mutex );
该函数为获得一个互斥锁,参数为指向要获取的互斥锁的句柄的指针
(3)OSStatus mico_rtos_unlock_mutex(mico_mutex_t* mutex );
该函数为释放一个互斥锁,参数为指向要释放的互斥锁的句柄的指针
三、MiCO互斥锁示例
该示例参数官方的测试demo,参考示例代码位于SDK_MiCOKit_v2.3.0.2DemosCOM.MXCHIP.BASICos,官网示例代码说明http://mico.io/wiki/doku.php?id=basic_os该示例为一个经典的生产者与消费者模型,一个线程负责生产,一个线程负责消费,由互斥量保证全局变量每次只有一个线程“拥有”。
  1. mico_mutex_t  mutex = NULL;
  2. int g_tickets = 1;//
  3. char *p_name1 = "consumption";
  4. char *p_name2 = "production";
  5. void  mutex_consumption(void *arg)//
  6. {
  7.   char *name = (char *)arg;
  8.     while(1){
  9.         mico_rtos_lock_mutex(&mutex);
  10.         if(g_tickets==1)
  11.         {
  12.             mico_os_log( "Thread exit %s",name );;
  13.             g_tickets=0;
  14.         }
  15.          mico_rtos_unlock_mutex(&mutex);
  16.     }
  17. }

  18. void  mutex_production(void *arg)
  19. {
  20.   char *name = (char *)arg;
  21.     while(1){
  22.         mico_rtos_lock_mutex(&mutex);
  23.         if(g_tickets==0)
  24.         {
  25.            mico_os_log( "Thread exit %s",name );;
  26.            g_tickets=1;
  27.         }
  28.          mico_rtos_unlock_mutex(&mutex);
  29.     }
  30. }

  31. void TestMiCOMutex(void)
  32. {
  33.      OSStatus err = kNoErr;

  34.   /* Create a mutex*/
  35.   err = mico_rtos_init_mutex( &mutex);
  36.   require_noerr(err, exit);

  37.   /* Create threads */
  38.   err = mico_rtos_create_thread( NULL, MICO_APPLICATION_PRIORITY+1, "consumption", mutex_consumption, 0x800, p_name1 );
  39.   require_noerr(err, exit);

  40.   err = mico_rtos_create_thread( NULL, MICO_APPLICATION_PRIORITY+1, "production", mutex_production, 0x800, p_name2 );
  41.   require_noerr(err, exit);
  42.   exit:
  43.   if( err != kNoErr )
  44.     mico_os_log( "Thread exit with err: %d", err );

  45.   mico_rtos_delete_thread(NULL);
  46. }


四、MiCO示例效果

QQ截图20151025014236.png

更多回帖

发帖
×
20
完善资料,
赚取积分