线程锁进行互斥访问(程序示例)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> pthread_mutex_t Device_mutex = PTHREAD_MUTEX_INITIALIZER; int count=0; void * thread_func1() { printf("thread id is %d\n",pthread_self()); while(1) { // printf("thread 1 ,sleep 20 ,quite c>=10,\n"); pthread_mutex_lock(&Device_mutex); printf("thread 1 ,sleep 20 ,quite c>=10, c=%d \n",count); count++; if(count>=10) { pthread_mutex_unlock(&Device_mutex); break; } else { pthread_mutex_unlock(&Device_mutex); } sleep(20); } printf(" thread 1 quite\n"); return NULL; } void * thread_func2() { printf("thread id is %d \n ",pthread_self()); while(1) { // printf("thread 2 ,sleep 5 ,quite c>=30,\n"); pthread_mutex_lock(&Device_mutex); printf("thread 2 ,sleep 5 ,quite c>=30, c= %d \n",count); count++; if(count>=30) { pthread_mutex_unlock(&Device_mutex); break; } else { pthread_mutex_unlock(&Device_mutex); } sleep(5); } printf(" thread 2 quite\n"); return NULL; } int main() { pthread_t thread1, thread2; // pthread_mutex_init(&Device_mutex,NULL); if(pthread_create(&thread1,NULL,thread_func1,NULL) == -1) { printf("create IP81 Thread error !n"); exit(1); } sleep(1); if(pthread_create(&thread2,NULL,thread_func2,NULL) == -1) { printf("create IP81_2 Thread error!n"); exit(1); } sleep(1); pthread_join(thread1,NULL); pthread_join(thread2,NULL); pthread_mutex_destroy(&Device_mutex); return 0; }
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点。linux下提供了多种方式来处理线程同步,最常用的是互斥、读写锁、条件变量和信号量。
1、互斥锁(mutex)
通过锁机制实现线程间的同步。同一时刻只允许一个线程执行一个关键部分的代码。
int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex *mutex);
int pthread_mutex_destroy(pthread_mutex *mutex);
int pthread_mutex_unlock(pthread_mutex *
(1)先初始化锁init()或静态赋值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER
attr_t有:
PTHREAD_MUTEX_TIMED_NP:其余线程等待队列
PTHREAD_MUTEX_RECURSIVE_NP:嵌套锁,允许线程多次加锁,不同线程,解锁后重新竞争
PTHREAD_MUTEX_ERRORCHECK_NP:检错,与一同,线程请求已用锁,返回EDEADLK;
PTHREAD_MUTEX_ADAPTIVE_NP:适应锁,解锁后重新竞争
(2)加锁,lock,trylock,lock阻塞等待锁,trylock立即返回EBUSY
(3)解锁,unlock需满足是加锁状态,且由加锁线程解锁
(4)清除锁,destroy(此时锁必需unlock,否则返回EBUSY,//Linux下互斥锁不占用内存资源