嵌入式Linux并发程序设计,线程,线程间通信--互斥,临界资源/临界区/互斥机制/互斥锁,pthr

2019-07-12 15:59发布

文章目录

1,临界资源

  1. 临界资源
    · 一次只允许一个任务(进程、线程)访问的共享资源
  2. 临界区
    ·访问临界资源的代码
    ·访问非临界资源的代码叫非临界区
  3. 互斥机制
    ·临界区互斥:当一个任务在访问临界区的时候,其他任务不能访问该临界区(相同的临界资源)
    ·mutex互斥锁:互斥锁只能被一个任务所持有。互斥锁有两种状态,空闲/只被一个任务所持有。
    ·任务访问临界资源前申请锁,访问完后释放锁。没有申请到锁的任务需要阻塞等待,直到持有这个锁为止

2,互斥锁的初始化pthread_mutex_init()

#include
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t * attr);
  1. 成功时返回0,失败时返回错误码
  2. mutex 指向要初始化的互斥锁对象
  3. attr 互斥锁属性,NULL表示缺省属性

3,申请锁pthread_mutex_lock()

#include
int pthread_mutex_lock(pthread_mutex_t *mutex);
  1. 成功时返回0,失败时返回错误码
  2. mutex 指向要初始化的互斥锁对象
  3. 如果无法获得锁,任务阻塞

4,释放锁pthread_mutex_unlock()

#include
int pthread_mutex_unlock(pthread_mutex_t *mutex);
  1. 成功时返回0,失败时返回错误码
  2. mutex 指向要初始化的互斥锁对象
  3. 执行完临界区要及时释放锁
  4. 如果有多个临界资源,比如一个任务每次都要同时访问两个临界资源,那这两个临界资源只需要一个互斥锁保护就行。如果这两个临界资源访问不是同时的,就需要两个互斥锁来分别保护

5,线程互斥—示例

#include #include #include #include #include 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 "); 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 ", value1, value2); usleep(100000); } #ifdef _LOCK_ pthread_mutex_unlock(&lock); #endif } return NULL; }
  1. 主线程中count++,之后会先把count赋给value1,再把count赋给value2;另外一个线程每隔100ms执行一次判断value1!=value2,如果不等于,分别打印value1和value2;
  2. 如果不上锁,主线程把count赋给value1后,如果还没来得及赋给value2,主线程的时间片用完了,系统自动调度到另外一个线程,就会出现value1!=value2的情况
  3. 如果上了互斥锁,就能让两个线程中的临界区代码严格互斥
不使用互斥锁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
  1. "-D"相当于传入宏定义