互斥锁和信号量很相似, RT-Thread 中的互斥锁也有静态和动态之分,和互斥锁有关的
操作如下:
初始化—rt_mutex_init()(对应静态互斥锁);
建立—rt_mutex_create()(对应动态互斥锁);
获取—rt_mutex_take();
释放—rt_ mutex_release();
脱离—rt_mutex_detach()( 对应静态信号量) ;
删除—rt_mutex_delete()( 对应动态信号量);

我们看到信号量和互斥锁如此形似,那么它们的区别在哪里?我以我的理解,区别一下这两个 IPC 对象:

1、信号量哪里都可以释放,但互斥锁只有获得了其控制权的线程才可以释放,即:只有“锁上”它的那个线程才有“钥匙”打开它,有“所有权”的概念。

2、信号量可能导致线程优先级反转,而互斥锁可通过优先级继承的方法解决优先级反转问题(详见《 RT-Thread 编程指南》) 。

实际中我们常遇到这样的情况,比如一个总线上挂接着 N 个设备,这是我们必须“分时”的去操作各个设备,这时候互斥锁就派上用场了:我们在开始操作某个设备前先使用
rt_mutex_take ()锁住总线,然后开始对设备的具体操作,最后通过 rt_mutex_release (),解锁总线,让给其他设备去使用。

信号量用于同步的时候就像交通灯,任务只有在获得许可的时候才可以运行,强调的是运行步骤;信号量用于互斥的时候就像一把钥匙,它强调只有获得钥匙的任务才可以运行,
强调的是许可和权限。这两者都不具备任何数据交换的功能,下面来介绍具有数据交换功能的 IPC 对象: 邮箱和消息队列。

/**********************************************************************************************************
*
* 模块名称 : 功能演示
* 文件名称 : test.c
* 版 本 : V1.0
* 说 明 :
* 修改记录 :
* 版本号 日期 作者 说明
*
* v1.0 2013-4-20 jiezhi320(UP MCU 工作室) 演示互斥锁的基本使用
*
* Copyright (C), 2012-2013,
* 淘宝店: http://shop73275611.taobao.com
* QQ交流群: 258043068
*
**********************************************************************************************************/
#include <rtthread.h>
#include <stm32f10x.h>
#include "test.h" /* 变量分配4字节对齐 */
ALIGN(RT_ALIGN_SIZE) /* 静态线程的 线程堆栈*/
static rt_uint8_t test1_stack[];
static rt_uint8_t test2_stack[]; /* 静态线程的 线程控制块 */
static struct rt_thread test1_thread;
static struct rt_thread test2_thread; /* 互斥量控制块 */
static struct rt_mutex static_mutex;
/* 指向互斥量的指针 */
static rt_mutex_t dynamic_mutex = RT_NULL; void test1_thread_entry(void* parameter)
{
rt_err_t result;
rt_tick_t tick; /* 1. staic mutex demo */ /* 试图持有互斥量,最大等待10个OS Tick后返回 */
rt_kprintf("thread1 try to get static mutex, wait 10 ticks.\n"); /* 获得当前的OS Tick */
tick = rt_tick_get();
result = rt_mutex_take(&static_mutex, ); if (result == -RT_ETIMEOUT)
{
/* 超时后判断是否刚好是10个OS Tick */
if (rt_tick_get() - tick != )
{
rt_mutex_detach(&static_mutex);
return;
}
rt_kprintf("thread1 take static mutex timeout\n");
}
else
{
/* 线程2持有互斥量,且在相当长的时间后才会释放互斥量,
* 因此10个tick后线程1不可能获得 */
rt_kprintf("thread1 take a static mutex, failed.\n");
rt_mutex_detach(&static_mutex);
return;
} /* 永久等待方式持有互斥量 */
rt_kprintf("thread1 try to get static mutex, wait forever.\n");
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* 不成功则测试失败 */
rt_kprintf("thread1 take a static mutex, failed.\n");
rt_mutex_detach(&static_mutex);
return;
} rt_kprintf("thread1 take a staic mutex, done.\n"); /* 脱离互斥量对象 */
rt_mutex_detach(&static_mutex); /* 2. dynamic mutex test */ /* 试图持有互斥量,最大等待10个OS Tick后返回 */
rt_kprintf("thread1 try to get dynamic mutex, wait 10 ticks.\n"); tick = rt_tick_get();
result = rt_mutex_take(dynamic_mutex, );
if (result == -RT_ETIMEOUT)
{
/* 超时后判断是否刚好是10个OS Tick */
if (rt_tick_get() - tick != )
{
rt_mutex_delete(dynamic_mutex);
return;
}
rt_kprintf("thread1 take dynamic mutex timeout\n");
}
else
{
/* 线程2持有互斥量,且在相当长的时间后才会释放互斥量,
* 因此10个tick后线程1不可能获得 */
rt_kprintf("thread1 take a dynamic mutex, failed.\n");
rt_mutex_delete(dynamic_mutex);
return;
} /* 永久等待方式持有互斥量 */
rt_kprintf("thread1 try to get dynamic mutex, wait forever.\n");
result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
/* 不成功则测试失败 */
rt_kprintf("thread1 take a dynamic mutex, failed.\n");
rt_mutex_delete(dynamic_mutex);
return;
} rt_kprintf("thread1 take a dynamic mutex, done.\n");
/* 删除互斥量对象 */
rt_mutex_delete(dynamic_mutex); } void test2_thread_entry(void* parameter)
{ /* 1. static mutex test */
rt_kprintf("thread2 try to get static mutex\n");
rt_mutex_take(&static_mutex, );
rt_kprintf("thread2 got static mutex\n");
rt_thread_delay(RT_TICK_PER_SECOND);
rt_kprintf("thread2 release static mutex\n");
rt_mutex_release(&static_mutex); /* 2. dynamic mutex test */
rt_kprintf("thread2 try to get dynamic mutex\n");
rt_mutex_take(dynamic_mutex, );
rt_kprintf("thread2 got dynamic mutex\n");
rt_thread_delay(RT_TICK_PER_SECOND);
rt_kprintf("thread2 release dynamic mutex\n");
rt_mutex_release(dynamic_mutex); } rt_err_t demo_thread_creat(void)
{
rt_err_t result; /* 初始化静态互斥量 */
result = rt_mutex_init(&static_mutex, "smutex", RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("init static mutex failed.\n");
return -;
} /* 创建一个动态互斥量 */
dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_FIFO);
if (dynamic_mutex == RT_NULL)
{
rt_kprintf("create dynamic mutex failed.\n");
return -;
} /* 创建test1线程 : 优先级 16 ,时间片 5个系统滴答 */
result = rt_thread_init(&test1_thread,
"test1",
test1_thread_entry, RT_NULL,
(rt_uint8_t*)&test1_stack[], sizeof(test1_stack), , ); if (result == RT_EOK)
{
rt_thread_startup(&test1_thread);
} /* 创建test2线程 : 优先级 15 ,时间片 5个系统滴答 */
result = rt_thread_init(&test2_thread,
"test2",
test2_thread_entry, RT_NULL,
(rt_uint8_t*)&test2_stack[], sizeof(test2_stack), , ); if (result == RT_EOK)
{
rt_thread_startup(&test2_thread);
}
return ;
}

RT-Thread互斥锁的更多相关文章

  1. linux thread 互斥锁

    #include <stdio.h> #include <stdlib.h> #include <pthread.h> void *threadhandle(voi ...

  2. 多线程编程之Apue3rd_Chapter11之互斥锁_读写锁_自旋锁

    学习了apue3rd的第11章,主要讲的是多线程编程.因为线程共享进程的资源比如堆和全局变量,多线程编程最重要的是,使用各种锁进行线程同步. 线程编程首先要学习的三个函数如下: #include &l ...

  3. C++ 并发编程之互斥锁和条件变量的性能比较

    介绍 本文以最简单生产者消费者模型,通过运行程序,观察该进程的cpu使用率,来对比使用互斥锁 和 互斥锁+条件变量的性能比较. 本例子的生产者消费者模型,1个生产者,5个消费者. 生产者线程往队列里放 ...

  4. Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

    本章对ReentrantLock包进行基本介绍,这一章主要对ReentrantLock进行概括性的介绍,内容包括:ReentrantLock介绍ReentrantLock函数列表ReentrantLo ...

  5. 异步与并行~ReaderWriterLockSlim实现的共享锁和互斥锁

    返回目录 在System.Threading.Tasks命名空间下,使用ReaderWriterLockSlim对象来实现多线程并发时的锁管理,它比lock来说,性能更好,也并合理,我们都知道lock ...

  6. c# 多线程 --Mutex(互斥锁)

    互斥锁(Mutex) 互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它. 互斥锁可适用于一个共享资源每次只能被一个线程访问的情况 函数: //创建一个处于未获取状态的互斥锁 Pub ...

  7. 互斥锁(Mutex)

    互斥锁(Mutex)互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它.互斥锁可适用于一个共享资源每次只能被一个线程访问的情况 函数://创建一个处于未获取状态的互斥锁Public ...

  8. JUC回顾之-可重入的互斥锁ReentrantLock

    1.什么是可重锁ReentrantLock? 就是支持重新进入的锁,表示该锁能够支持一个线程对资源的重复加锁. 2.ReentrantLock分为公平锁和非公平锁:区别是在于获取锁的机制上是否公平. ...

  9. zookeeper实现互斥锁

    简单的说,zookeeper就是为了解决集群环境中数据一致性的问题. 举个很简单栗子: 有一个变量A,分别存在于两台服务器中,某个程序需要用到变量A,就随机地访问其中一台服务器并取得变量A的值,对吧? ...

  10. linux多线程编程之互斥锁

    多线程并行运行,共享同一种互斥资源时,需要上互斥锁来运行,主要是用到pthread_mutex_lock函数和pthread_mutex_unlock函数对线程进行上锁和解锁 下面是一个例子: #in ...

随机推荐

  1. 【ASP.NET MVC】个人复习整理

    1.为 Action 标注 Attribute 限制访问 public class HomeController : Controller { [HttpPost] public ActionResu ...

  2. 解决页面插入HTML代码后错位(HTML代码里的标签不完整导致错位)

    这个的例子是从数据库读取出来的数据内容包含HTML导致页面错位问题! 解决办法如下: 首先过滤掉会跟JS冲突的字符,C#代码如下: string htmlc = Model.HtmlContents. ...

  3. PHP 判断数组里的值是否有存在

     一维数组检测<?php  $a = array('as','ddf','ddf','as','qwe','wer','ert'); $res = array_unique($a); var_d ...

  4. hdu 2444 二分图判断与最大匹配

    题意:有n个学生,有m对人是认识的,每一对认识的人能分到一间房,问能否把n个学生分成两部分,每部分内的学生互不认识,而两部分之间的学生认识.如果可以分成两部分,就算出房间最多需要多少间,否则就输出No ...

  5. hdu 4622 **

    题意:Suppose there are the symbols M, I, and U which can be combined to produce strings of symbols cal ...

  6. ERStudio的使用

    转自于:http://www.cnblogs.com/TangPro/p/3250320.html 打开ERstudio,点击新建出现如图对话框: 选择第一个,表示创建一个新的关系型 数据库模型 这里 ...

  7. loj 1154(最大流+枚举汇点)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26868 思路:拆点,容量为最多能跳的步数,然后设立一个超级源点,源 ...

  8. 帧动画FrameAnimation

    <!-- 布局 --> <item android:drawable="@drawable/girl_1" android:duration="100& ...

  9. HTTP基础04--web服务器

    单台虚拟主机实现多个域名 由于虚拟服务器的功能,一台HTTP服务器可以搭建多个Web站点: 在互联网上,域名通过 DNS 服务映射到 IP 地址(域名解析)之后访问目标网站.当请求发送到服务器时,已经 ...

  10. BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)

    挺直白的构图..最小费用最大流的定义. #include<cstdio> #include<cstring> #include<queue> #include< ...