互斥锁
这是本章主要讨论的东西。互斥锁的含义不再具体解释,这里只描述如何在pthread下使用互斥锁。
对互斥锁的主要操作包括:
pthread_mutex_init() 初始化一个互斥锁
pthread_mutex_destroy() 销毁互斥锁
pthread_mutex_lock() 对互斥锁上锁
pthread_mutex_lock() 对互斥锁解锁
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
参数 | 描述 |
---|---|
mutex | 互斥锁句柄,不能为NULL |
attr | 指向互斥锁属性的指针,若该指针NULL,则使用默认的属性。 |
这个程序会初始化2个线程,它们拥有相同的优先级,2个线程都会调用同一个printer()函数输出自己的字符串,printer()函数每次只输出一个字符,之后休眠1秒,调用printer()函数的线程同样也休眠。如果不使用互斥锁,线程1打印了一个字符,休眠后执行线程2,线程2打印一个字符,这样就不能完整的打印线程1和线程2的字符串,打印出的字符串是混乱的。如果使用了互斥锁保护2个线程共享的打印函数printer(),线程1拿到互斥锁后执行printer()打印函数打印一个字符,之后休眠1秒,这是切换到线程2,因为互斥锁已经被线程1上锁,线程2将阻塞,直到线程1的字符串打印完整后主动释放互斥锁后线程2才会被唤醒。
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
/* 线程控制块 */
static pthread_t tid1;
static pthread_t tid2;
/* 互斥锁控制块 */
static pthread_mutex_t mutex;
/* 线程共享的打印函数 */
static void printer(char* str)
{
while(*str != 0)
{
putchar(*str); /* 输出一个字符 */
str++;
sleep(1); /* 休眠1秒 */
}
printf("\n");
}
/* 函数返回值检查 */
static void check_result(char* str,int result)
{
if (0 == result)
{
printf("%s successfully!\n",str);
}
else
{
printf("%s failed! error code is %d\n",str,result);
}
}
/*线程入口*/
static void* thread1_entry(void* parameter)
{
char* str = "thread1 hello RT-Thread";
while (1)
{
pthread_mutex_lock(&mutex); /* 互斥锁上锁 */
printer(str); /* 访问共享打印函数 */
pthread_mutex_unlock(&mutex); /* 访问完成后解锁 */
sleep(2); /* 休眠2秒 */
}
}
static void* thread2_entry(void* parameter)
{
char* str = "thread2 hi world";
while (1)
{
pthread_mutex_lock(&mutex); /* 互斥锁上锁 */
printer(str); /* 访问共享打印函数 */
pthread_mutex_unlock(&mutex); /* 访问完成后解锁 */
sleep(2); /* 休眠2秒 */
}
}
/* 用户应用入口 */
int rt_application_init()
{
int result;
/* 初始化一个互斥锁 */
pthread_mutex_init(&mutex,NULL);
/*创建线程1,线程入口是thread1_entry, 属性参数为NULL选择默认值,入口参数是NULL*/
result = pthread_create(&tid1,NULL,thread1_entry,NULL);
check_result("thread1 created",result);
/*创建线程2,线程入口是thread2_entry, 属性参数为NULL选择默认值,入口参数是NULL*/
result = pthread_create(&tid2,NULL,thread2_entry,NULL);
check_result("thread2 created",result);
return 0;
}
int main()
{
rt_application_init();
while(1);
return 0;
}
文章参考自:https://www.bookstack.cn/read/rtthread-manual-doc/16.4.md