目录
- 一、互斥锁的介绍
- 二、使用方法
- 三、测试代码
一、互斥锁的介绍
在Linux系统中,特别是在ARM架构的嵌入式系统中,互斥量(Mutex)用于保护共享资源不被多个线程或任务同时访问,从而防止数据竞争和不一致性。
POSIX 互斥信号量的类型为 pthread_mutex_t。使用时需要定义一个 pthread_mutex_t 类型的变量,如:
pthread_mutex_t mutex;
二、使用方法
互斥量是一个对象,它可以被锁定(locked)和解锁(unlocked)。当一个线程或任务锁定了一个互斥量时,其他任何试图锁定该互斥量的线程或任务都将被阻塞,直到该互斥量被解锁。
①初始化:在使用互斥量之前,必须对其进行初始化。这通常是通过调用一个特定的函数(如pthread_mutex_init)来完成的。
②锁定与解锁:当线程或任务需要访问共享资源时,它应该首先锁定互斥量,使用pthread_mutex_lock 函数,如果互斥量已经被另一个线程或任务锁定,则当前线程或任务将被阻塞,直到互斥量被解锁。访问完共享资源后,线程或任务应该解锁互斥量,使用 pthread_mutex_unlock 函数,以便其他线程或任务可以访问它。
③销毁:当不再需要互斥量时,应该销毁它,以释放与之关联的资源。这通常是通过调用一个特定的函数(如pthread_mutex_destroy)来完成的。
④类型:在POSIX线程(pthreads)库中,有两种主要的互斥量类型,分别是正常互斥量(normal mutex)和递归互斥量(recursive mutex)。正常互斥量不允许同一个线程多次锁定它,而递归互斥量则允许。
一个 POSIX 互斥信号量使用以前必须首先进行初始化,可以把 mutex 初始值设置为PTHREAD_MUTEX_INITIALIZER(静态初始化),也可以调用 pthread_mutex_init 函数进行动态初始化。
线程如果需要等待一个互斥信号量,可以调用pthread_mutex_lock 函数。释放一个互斥信号量使用 pthread_mutex_unlock 函数。
当一个互斥信号量使用完毕后,应该调用 pthread_mutex_destroy 函数将其删除。需要注意的是,如果试图再次使用一个被删除的信号量,将出现未知的错误。
三、测试代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
// 定义一个全局变量作为共享资源
int counter = 0;
// 定义一个互斥量用于保护counter
pthread_mutex_t mutex;
// 无参 线程函数,用于增加counter的值
/*
void* increment_counter(void* arg) {
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
for (int i = 0; i < 5; i++) {
// 锁定互斥量
pthread_mutex_lock(&mutex);
counter++;
printf("pid %lu tid %lu (0x%lx)\n", (unsigned long)pid,(unsigned long)tid, (unsigned long)tid);
printf("counter = %d\r\n",counter);
// 解锁互斥量
pthread_mutex_unlock(&mutex);
}
return NULL;
}
*/
// 有参 线程函数,用于增加counter的值
void* increment_counter(void* arg) {
int tmp = *(int *)arg;
for (int i = 0; i < 5; i++) {
// 锁定互斥量
pthread_mutex_lock(&mutex);
counter++;
printf("num = %d \r\n",tmp);
printf("counter = %d \r\n",counter);
// 解锁互斥量
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
// 初始化互斥量
pthread_mutex_init(&mutex, NULL);
// 创建两个线程,每个线程都会增加counter的值
pthread_t thread1, thread2;
//无参
//pthread_create(&thread1, NULL, increment_counter, NULL);
//pthread_create(&thread2, NULL, increment_counter, NULL);
//有参
int num1=1;
int num2=2;
pthread_create(&thread1, NULL, increment_counter, &num1);
pthread_create(&thread2, NULL, increment_counter, &num2);
// 等待两个线程完成
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
// 打印最终的counter值(应该是10)
printf("Final counter value: %d\n", counter);
// 销毁互斥量
pthread_mutex_destroy(&mutex);
return 0;
}
测试结果,如下: