文章目录
1,临界资源
- 临界资源
· 一次只允许一个任务(进程、线程)访问的共享资源 - 临界区
·访问临界资源的代码
·访问非临界资源的代码叫非临界区 - 互斥机制
·临界区互斥:当一个任务在访问临界区的时候,其他任务不能访问该临界区(相同的临界资源)
·mutex互斥锁:互斥锁只能被一个任务所持有。互斥锁有两种状态,空闲/只被一个任务所持有。
·任务访问临界资源前申请锁,访问完后释放锁。没有申请到锁的任务需要阻塞等待,直到持有这个锁为止
2,互斥锁的初始化pthread_mutex_init()
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t * attr);
- 成功时返回0,失败时返回错误码
- mutex 指向要初始化的互斥锁对象
- attr 互斥锁属性,NULL表示缺省属性
3,申请锁pthread_mutex_lock()
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
- 成功时返回0,失败时返回错误码
- mutex 指向要初始化的互斥锁对象
- 如果无法获得锁,任务阻塞
4,释放锁pthread_mutex_unlock()
#include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex);
- 成功时返回0,失败时返回错误码
- mutex 指向要初始化的互斥锁对象
- 执行完临界区要及时释放锁
- 如果有多个临界资源,比如一个任务每次都要同时访问两个临界资源,那这两个临界资源只需要一个互斥锁保护就行。如果这两个临界资源访问不是同时的,就需要两个互斥锁来分别保护
5,线程互斥—示例
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <semaphore.h>
unsigned int count, value1, value2;
pthread_mutex_t lock;
void *function(void *arg);
int main(void)
{
pthread_t a_thread;
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("fail to pthread_mutex_init\n"); exit(-1);
}
if (pthread_create(&a_thread, NULL, function, NULL) != 0)
{
printf("fail to PTHREAD_CREATE_JOINABLEeate"); exit(-1);
}
while ( 1 ) //主线程
{
count++;
#ifdef _LOCK_
pthread_mutex_lock(&lock);
#endif
value1 = count;
value2 = count;
#ifdef _LOCK_
pthread_mutex_unlock(&lock);
#endif
}
return 0;
}
void *function(void *arg)
{
while ( 1 )
{
#ifdef _LOCK_
pthread_mutex_lock(&lock);
#endif
if (value1 != value2)
{
printf("value1 = %u, value2 = %u\n", value1, value2);
usleep(100000);
}
#ifdef _LOCK_
pthread_mutex_unlock(&lock);
#endif
}
return NULL;
}
- 主线程中count++,之后会先把count赋给value1,再把count赋给value2;另外一个线程每隔100ms执行一次判断value1!=value2,如果不等于,分别打印value1和value2;
- 如果不上锁,主线程把count赋给value1后,如果还没来得及赋给value2,主线程的时间片用完了,系统自动调度到另外一个线程,就会出现value1!=value2的情况
- 如果上了互斥锁,就能让两个线程中的临界区代码严格互斥
不使用互斥锁
gcc sem3.c -o sem3.out -lpthread
linux@linux:~/test/pthread$ gcc sem3.c -o sem3.out -lpthread
linux@linux:~/test/pthread$ ./sem3.out
value1 = 3052903, value2 = 3052902
value1 = 38157180, value2 = 38157179
value1 = 72179985, value2 = 72179984
value1 = 107488282, value2 = 107488281
value1 = 141249026, value2 = 141249025
value1 = 171859486, value2 = 171859485
使用互斥锁
gcc sem3.c -o sem3.out -lpthread -D_LOCK_
linux@linux:~/test/pthread$ gcc sem3.c -o sem3.out -lpthread -D_LOCK_
linux@linux:~/test/pthread$ ./sem3.out
- "-D"相当于传入宏定义