多线程的同步和互斥

来源:互联网 发布:sql replace替换多个 编辑:程序博客网 时间:2024/06/13 10:53

1.互斥锁的定义

互斥锁,是一种信号量,常用来防止两个进程或线程在同一时刻访问相同的共享资源。从本质上讲,互斥量是一把锁,该锁保护一个或者一些资源。一个线程如果需要访问该资源,必须要获得互斥量对其加锁。这时,如果其他线程想访问该资源也必须要获得该互斥量,但是锁已经加锁,所以这些进程只能阻塞,直到获得该锁的进程解锁。这时阻塞的线程里面有一个线程获得该互斥量并加锁,获准访问该资源,其他进程继续阻塞,周而复始。

2.互斥锁的初始化

Pthread_mutex_init函数

函数作用:用于初始化互斥锁

函数原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);

参数:mutex:互斥锁

      Attr:PTHREAD_MUTEX_INITIALIZER 创建快速互斥锁

  PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP 创建递归互斥锁

  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP 创建检错互斥锁

返回值:成功返回0;出错返回-1

3.互斥锁操作的实现机制

下面是一个使用互斥锁的例子,在线程1和线程2中分别打印提示信息,通过使用互斥锁来控制线程1和线程2运行的先后顺序

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <stdio.h>  
  2. #include <pthread.h>  
  3. #include <stdlib.h>  
  4.    
  5. pthread_mutex_t mutex;  
  6.    
  7. void *thread1(void)  
  8. {  
  9.     int i;  
  10.     pthread_mutex_lock(&mutex);  
  11.    
  12.     for(i = 0; i < 4; i++)  
  13.     {  
  14.         printf("this is the 1st pthread\n");  
  15. sleep(1);  
  16.     }  
  17.    
  18.     pthread_mutex_unlock(&mutex);  
  19. }  
  20.    
  21. void *thread2(void)  
  22. {  
  23.     int i;  
  24.     pthread_mutex_lock(&mutex);  
  25.    
  26.     for(i = 0; i < 4; i++)  
  27.     {  
  28.         printf("this is the 2nd pthread\n");  
  29. sleep(1);  
  30.     }  
  31.    
  32.     pthread_mutex_unlock(&mutex);  
  33. }  
  34.    
  35. int main()  
  36. {  
  37.     pthread_t id1,id2;  
  38.       
  39.     if(pthread_mutex_init(&mutex,NULL) != 0)  
  40.     {  
  41.         printf("init failed!\n");  
  42. exit(1);  
  43.     }  
  44.     if(pthread_create(&id1,NULL,(void *)thread1,NULL) != 0)  
  45.     {  
  46.         printf("create thread1 failed!\n");  
  47. exit(1);  
  48.     }  
  49.     if(pthread_create(&id2,NULL,(void *)thread2,NULL) != 0)  
  50.     {  
  51.         printf("create thread2 failed!\n");  
  52. exit(1);  
  53.     }  
  54.    
  55.     pthread_join(id1,NULL);  
  56.     pthread_join(id2,NULL);  
  57.    
  58.     sleep(1);  
  59.     return 0;  
  60. }  

二、信号量实现线程之间的PV操作,实现线程同步和互斥的数据模型?

1.sem_init函数

函数作用:初始化信号量

函数原型:int sem_init(sem_t *sem, int pshared, unsigned int value)

参数:sem:信号量指针

      Pshared:决定信号量能否在几个进程间共享,一般取0

      Value:信号量的初始值

 

2.信号的操作

Int sem_wait(sem_t *sem);    P操作    

Int sem_try_wait(sem_t *sem);

Int sempost(sem_t *sem);    V操作

Int sem_getvalue(sem_t *sem);

Int sem_destroy(sem_t *sem);    销毁信号

 

3.用信号的PV操作来实现消费者和生产者的机制

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <pthread.h>  
  4. #include <stdlib.h>  
  5. #include <semaphore.h>  
  6. #include <fcntl.h>  
  7. #include <unistd.h>  
  8. #include <sys/ipc.h>  
  9.   
  10. #define MAX_SIZE 1024  
  11.    
  12. sem_t sem1,sem2;  
  13. char buff[MAX_SIZE];  
  14.    
  15. void producer(void *arg)  
  16. {  
  17.     do  
  18.     {  
  19.         sem_wait(&sem1);  
  20.         printf("Producer enter some data:");  
  21. scanf("%s",buff);  
  22. sem_post(&sem2);  
  23.           
  24.     }while(strncmp(buff,"quit",4) != 0);  
  25. }  
  26.    
  27. void customer(void *arg)  
  28. {  
  29.     do  
  30.     {  
  31.         sem_wait(&sem2);  
  32.         printf("Customer read is:%s\n",buff);  
  33. sem_post(&sem1);  
  34.           
  35.     }while(strncmp(buff,"quit",4) != 0);  
  36. }  
  37.    
  38. int main()  
  39. {  
  40.     pthread_t id1,id2;  
  41.    
  42.     sem_init(&sem1,0,1);  
  43.     sem_init(&sem2,0,0);  
  44.    
  45.     if(pthread_create(&id1,NULL,(void *)producer,NULL) != 0)  
  46.     {  
  47.         printf("init producer error!\n");  
  48. return -1;  
  49.     }  
  50.     if(pthread_create(&id2,NULL,(void *)customer,NULL) != 0)  
  51.     {  
  52.         printf("init customer error!\n");  
  53. return -1;  
  54.     }  
  55.    
  56.     pthread_join(id1,NULL);  
  57.     pthread_join(id2,NULL);  
  58.    
  59.     return 0;  
  60. }  
0 0
原创粉丝点击