互斥量(Mutex)用于解决共享资源的访问冲突。比如一个串口,如果两个线程同时访问,各自输出一个字符串;或者一个线程输出字符串到一半时,被另一个更高优先级的线程抢占,也要输出字符串。就可能出现串口输出数据的错乱。这时,用Mutex来管理串口的访问权,当一个线程在使用的时候,禁止其他线程访问,直到该线程释放串口访问权。
打开mbed官网,找到Mutex相关内容,在此主要是分析其中的例程。
Mutex的相关内容的开头,给出了Mutex的用途描述是:实现线程的同步,如保护共享资源的访问。接着是一个警告:Mutex的方法(函数)不能在ISR中调用。
下面是一个使用例程:演示如何用Mutex解决多线程调用printf()函数对串口访问的冲突。
#include “mbed.h”#include “rtos.h”Mutex stdio_mutex; void notify(const char* name, int state) { stdio_mutex.lock(); printf(“%s: %d/n/r”, name, state); stdio_mutex.unlock();}void test_thread(void const *args) { while (true) { notify((const char*)args, 0); Thread::wait(1000); notify((const char*)args, 1); Thread::wait(1000); }}int main() { Thread t2(test_thread, (void *)“Th 2”); Thread t3(test_thread, (void *)“Th 3”); test_thread((void *)“Th 1”);}
程序分析:
在main函数中,创建了两个线程,他们的名称分别为t2和t3,并且他们的任务函数都是test_thread,只是传入的参数不同。然后,main函数中调用test_thread((void *)“Th 1“);在这里test_thread()只是一个普通函数。
这样,程序就同时运行了3个线程:t2,t3以及main函数所在的主线程,他们运行的是test_thread()的3个不同副本。每个test_thread()的副本都调用了notify()函数和Thread :: wait(1000),而notify()调用了printf()函数,即通过串口输出数据。
在mbed OS调度过程中,就有可能出现下面的情况:当一个线程正在调用printf()打印数据的时候,调度器切换到另一个线程,而这个线程也正在调用printf()。这就会造成打印信息的混叠现象。
例句中给出了解决方案。就是定义一个互斥量,Mutex stdio_mutex;,然后在notify()函数中调用printf()前后分别加了stdio_mutex.lock();和stdio_mutex.unlock();。当两个线程调用notify()函数时,后一个线程必须等待前一个线程完成stdio_mutex.unlock();解锁互斥量。这样,就保证了每个线程在调用notify()函数时,都能打印出完整的一条信息。
互斥量(Mutex)用于解决共享资源的访问冲突。比如一个串口,如果两个线程同时访问,各自输出一个字符串;或者一个线程输出字符串到一半时,被另一个更高优先级的线程抢占,也要输出字符串。就可能出现串口输出数据的错乱。这时,用Mutex来管理串口的访问权,当一个线程在使用的时候,禁止其他线程访问,直到该线程释放串口访问权。
打开mbed官网,找到Mutex相关内容,在此主要是分析其中的例程。
Mutex的相关内容的开头,给出了Mutex的用途描述是:实现线程的同步,如保护共享资源的访问。接着是一个警告:Mutex的方法(函数)不能在ISR中调用。
下面是一个使用例程:演示如何用Mutex解决多线程调用printf()函数对串口访问的冲突。
#include “mbed.h”#include “rtos.h”Mutex stdio_mutex; void notify(const char* name, int state) { stdio_mutex.lock(); printf(“%s: %d/n/r”, name, state); stdio_mutex.unlock();}void test_thread(void const *args) { while (true) { notify((const char*)args, 0); Thread::wait(1000); notify((const char*)args, 1); Thread::wait(1000); }}int main() { Thread t2(test_thread, (void *)“Th 2”); Thread t3(test_thread, (void *)“Th 3”); test_thread((void *)“Th 1”);}
程序分析:
在main函数中,创建了两个线程,他们的名称分别为t2和t3,并且他们的任务函数都是test_thread,只是传入的参数不同。然后,main函数中调用test_thread((void *)“Th 1“);在这里test_thread()只是一个普通函数。
这样,程序就同时运行了3个线程:t2,t3以及main函数所在的主线程,他们运行的是test_thread()的3个不同副本。每个test_thread()的副本都调用了notify()函数和Thread :: wait(1000),而notify()调用了printf()函数,即通过串口输出数据。
在mbed OS调度过程中,就有可能出现下面的情况:当一个线程正在调用printf()打印数据的时候,调度器切换到另一个线程,而这个线程也正在调用printf()。这就会造成打印信息的混叠现象。
例句中给出了解决方案。就是定义一个互斥量,Mutex stdio_mutex;,然后在notify()函数中调用printf()前后分别加了stdio_mutex.lock();和stdio_mutex.unlock();。当两个线程调用notify()函数时,后一个线程必须等待前一个线程完成stdio_mutex.unlock();解锁互斥量。这样,就保证了每个线程在调用notify()函数时,都能打印出完整的一条信息。
举报