多线程编程:互斥
多线程共享一个进程的地址空间虽然线程间通信容易进行,但是多线程同时访问共享对象时需要引入同步和互斥机制。
1.线程间的互斥,引入互斥锁的目的是用来保证共享资源数据操作的完整性。
互斥锁主要用来保护临界资源,每个邻界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源。线程必须先获得互斥锁才能访问临界资源,访问完临界资源后释放该锁。如果无法获得锁,线程会阻塞知道获得锁为止。
2同步指的是多个任务按照约定的顺序相互配合完成一件事情,
1#include<stdio.h>2#include<pthread.h>3intg_count=0;4void*pthread_run(void*arg)5{6intcount=5000;7inttmp;8while(count--)9{10tmp=g_count;11printf("pthread_id:%d,g_count:%d\n",(int)arg,tmp);12g_count=tmp+1;13}14return(void*)0;15}16intmain()17{18pthread_ttid1,tid2;19pthread_create(&tid1,NULL,pthread_run,(void*)1);20pthread_create(&tid2,NULL,pthread_run,(void*)2);21sleep(1);22printf("finally,g_count:%d\n",g_count);23return0;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>3pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;4intg_count=0;5void*pthread_run(void*arg)6{7intcount=5000;8inttmp;9while(count--)10{11pthread_mutex_lock(&mutex);12tmp=g_count;13printf("pthread_id:%d,g_count:%d\n",(int)arg,tmp);14g_count=tmp+1;15pthread_mutex_unlock(&mutex);16}17return(void*)0;18}19intmain()20{21pthread_ttid1,tid2;22pthread_create(&tid1,NULL,pthread_run,(void*)1);23pthread_create(&tid2,NULL,pthread_run,(void*)2);24sleep(1);25pthread_mutex_destroy(&mutex);26printf("finally,g_count:%d\n",g_count);27return0;28}
总结:加锁时应该考虑问题的规模选择加锁的粒度,应从安全,性能,稳定性三方面来考虑。
加锁时,粒度越大,申请锁的次数少,申请锁时会占代码资源;
加锁加的越早,并行性能降低,程序执行效率也随之降低。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。