多线程共享一个进程的地址空间虽然线程间通信容易进行,但是多线程同时访问共享对象时需要引入同步和互斥机制。
1.线程间的互斥,引入互斥锁的目的是用来保证共享资源数据操作的完整性。
互斥锁主要用来保护临界资源,每个邻界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源。线程必须先获得互斥锁才能访问临界资源,访问完临界资源后释放该锁。如果无法获得锁,线程会阻塞知道获得锁为止。
2同步指的是多个任务按照约定的顺序相互配合完成一件事情,
1 #include<stdio.h> 2 #include<pthread.h> 3 int g_count=0; 4 void* pthread_run(void* arg) 5 { 6 int count=5000; 7 int tmp; 8 while(count--) 9 { 10 tmp=g_count; 11 printf("pthread_id:%d ,g_count: %d\n",(int)arg,tmp); 12 g_count=tmp+1; 13 } 14 return (void*)0; 15 } 16 int main() 17 { 18 pthread_t tid1,tid2; 19 pthread_create(&tid1,NULL,pthread_run,(void*)1); 20 pthread_create(&tid2,NULL,pthread_run,(void*)2); 21 sleep(1); 22 printf("finally,g_count: %d\n",g_count); 23 return 0; 24 }
按照预期结果,应该打印出10000,把g_count加10000次
但是,
这是因为两个线程同时对全局变量进行操作时产生干扰。
多线程的互斥操作主要用互斥量来实现,保护临界资源,对临界区加锁。
#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);//attr一般使用默认值为NULL
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
加锁,去锁函数
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);//阻塞式
int pthread_mutex_trylock(pthread_mutex_t *mutex);//非阻塞式
int pthread_mutex_unlock(pthread_mutex_t *mutex);
实现加锁
1 #include<stdio.h> 2 #include<pthread.h> 3 pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER; 4 int g_count=0; 5 void* pthread_run(void* arg) 6 { 7 int count=5000; 8 int tmp; 9 while(count--) 10 { 11 pthread_mutex_lock(&mutex); 12 tmp=g_count; 13 printf("pthread_id:%d ,g_count: %d\n",(int)arg,tmp); 14 g_count=tmp+1; 15 pthread_mutex_unlock(&mutex); 16 } 17 return (void*)0; 18 } 19 int main() 20 { 21 pthread_t tid1,tid2; 22 pthread_create(&tid1,NULL,pthread_run,(void*)1); 23 pthread_create(&tid2,NULL,pthread_run,(void*)2); 24 sleep(1); 25 pthread_mutex_destroy(&mutex); 26 printf("finally,g_count: %d\n",g_count); 27 return 0; 28 }
总结:加锁时应该考虑问题的规模选择加锁的粒度,应从安全,性能,稳定性三方面来考虑。
加锁时,粒度越大,申请锁的次数少,申请锁时会占代码资源;
加锁加的越早,并行性能降低,程序执行效率也随之降低。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。