互斥锁和信号量很相似, 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. android wifi驱动移植详细过程

    转自:http://bbs.imp3.net/thread-10558924-1-1.html 对于刚入手android没多久的人来说,android wifi 驱动的移植确实还是有难度的,不过参考了 ...

  2. CSS3 background-size 属性值:cover

    当设置值为cover,可以呈现出图片铺满浏览器内容的视觉效果 实例 规定背景图像的尺寸: div { background:url(img_flwr.gif); background-size:80p ...

  3. Hark的数据结构与算法练习之锦标赛排序

    算法说明 锦标赛排序是选择排序的一种. 实际上堆排序是锦标赛排序的优化版本,它们时间复杂度都是O(nlog2n),不同之处是堆排序的空间复杂度(O(1))远远低于锦标赛的空间复杂度(O(2n-1)) ...

  4. CodeForces 300C --数论

    A - A Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  5. 二分查找法 java

    前几天去面试,让我写二分查找法,真是哔了狗! 提了离职申请,没事写写吧! 首先二分查找是在一堆有序的序列中找到指定的结果. public class Erfen { public static int ...

  6. sssssssss

    构造函数new A 和new A()的区别,都是A类的实例化,后者可以向构造函数传参数. a=f(),指向window a=new f()指向当前函数的实例. Return b和return b()区 ...

  7. HierarchyRequestError:Node cannot be inserted at the specified point in the hierarchy

    问题描述: 用jquery的ajax加载html片段,出现该错误 HierarchyRequestError:Node cannot be inserted at the specified poin ...

  8. 简单几何(直线求交点) POJ 2074 Line of Sight

    题目传送门 题意:从一条马路(线段)看对面的房子(线段),问连续的能看到房子全部的最长区间 分析:自己的思路WA了:先对障碍物根据坐标排序,然后在相邻的障碍物的间隔找到区间,这样还要判断是否被其他障碍 ...

  9. Quartz.Net 配置模板范例

        1.App.config <?xml version="1.0" encoding="utf-8"?> <configuration& ...

  10. 转:.NET获取当前方法名或调用此方法的方法名

    Introduction Before .NET, we were always looking for a way to log current method name in a log file ...