互斥锁限制共享资源的访问
主线程中有两个线程,分别输出信息。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>int g_data=0;void* fun1(void *arg)
{printf("t1:%ld thread is create\n", (unsigned long)pthread_self());printf("t1: %d\n", *((int*)arg));while(1){printf("t1:%d\n", g_data++);sleep(1);}
}void* fun2(void *arg)
{printf("t2:%ld thread is create\n", (unsigned long)pthread_self());printf("t2: %d\n", *((int*)arg));while(1){printf("t2:%d\n", g_data++);sleep(1);}
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;// 线程属性 线程函数 线程函数参数ret = pthread_create(&t1, NULL, fun1, (void*)¶m);if(ret == 0){printf("main:create t1 success\n");} else {perror("why t1 fail");}ret = pthread_create(&t2, NULL, fun2, (void*)¶m);if(ret == 0){printf("main:create t1 success\n");} else {perror("why t2 fail");}printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程IDwhile(1){printf("main:%d\n", g_data);sleep(1);}pthread_join(t1, NULL);//等待线程结束,防止进程结束,线程还未执行完毕pthread_join(t2, NULL);//等待线程结束,防止进程结束,线程还未执行完毕return 0;
}
如何能确保 3 一定在 线程1 中输出呢?我们就需要用到“锁”这个东西了。
一定要线程1 先运行 并且保证能输出3。
t1刚开始执行到while循环时候,就让它加锁,不让其它线程对共享资源访问【无论是否t2先执行,最终1s后都会轮到t1加锁,因为t2中释放锁后存在sleep函数,而t1没有】,循环一直执行,直到等到3 结束。因为当t1执行while循环时,t2就不能对g_data进行修改。
加锁后的修改:
//demo6
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>int g_data=0;
pthread_mutex_t mutex;void* fun1(void *arg)
{printf("t1:%ld thread is create\n", (unsigned long)pthread_self());printf("t1: %d\n", *((int*)arg));pthread_mutex_lock(&mutex);while(1){printf("t1:%d\n", g_data++);sleep(1);if(g_data == 3){pthread_mutex_unlock(&mutex);printf("t1 quit================\n");pthread_exit(NULL);}}
}void* fun2(void *arg)
{printf("t2:%ld thread is create\n", (unsigned long)pthread_self());printf("t2: %d\n", *((int*)arg));while(1){printf("t2:%d\n", g_data);pthread_mutex_lock(&mutex);g_data++;pthread_mutex_unlock(&mutex);sleep(1);}
}int main()
{int ret;int param = 100;pthread_t t1;pthread_t t2;pthread_mutex_init(&mutex, NULL);// 线程属性 线程函数 线程函数参数ret = pthread_create(&t1, NULL, fun1, (void*)¶m);if(ret == 0){printf("main:create t1 success\n");} else {perror("why t1 fail");}ret = pthread_create(&t2, NULL, fun2, (void*)¶m);if(ret == 0){printf("main:create t1 success\n");} else {perror("why t2 fail");}printf("main:%ld\n", (unsigned long)pthread_self());//打印主线程IDwhile(1){printf("main:%d\n", g_data);sleep(1);}pthread_join(t1, NULL);//等待线程结束,防止进程结束,线程还未执行完毕pthread_join(t2, NULL);//等待线程结束,防止进程结束,线程还未执行完毕pthread_mutex_destroy(&mutex);return 0;
}
线程调用exit() 能让进程结束。所以线程中调用pthread_exit()函数
运行结果:可以看到,在t1中顺利退出,说明对互斥锁对共享资源的限制起作用了。
利用互斥锁对临界资源进行访问,主要是对全局变量的访问。为获取对共享资源的访问权限,t1线程是不断对全局变量访问,t2是做加法的时候才访问,而且加之后有1秒的延时。所以,t1肯定会先执行到3,即使t2先执行,也就执行一次,加一次就释放锁,t1还会拿到共享资源。
条件+互斥锁 更加智能。