多线程共享一个进程的地址空间虽然线程间通信容易进行,但是多线程同时访问共享对象时需要引入同步和互斥机制。
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 }
总结:加锁时应该考虑问题的规模选择加锁的粒度,应从安全,性能,稳定性三方面来考虑。
加锁时,粒度越大,申请锁的次数少,申请锁时会占代码资源;
加锁加的越早,并行性能降低,程序执行效率也随之降低。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。