关于linux的读写锁
这次当我给面试官提及到读写锁的时候,详细问了我的读写锁,我知道怎么回事,用法,但是具体没实践过,听过的还是不要给面试官说了,不然又给自己挖坑。 下面这个程序就是读写锁的程序,分别有两个读者,两个写着,当写着输入end的时候并且读者读到程序运行结束,里面的读写锁是动态初始化,最后用pthread_join(),主要主线程等待子线程运行完她才可以结束。对于现在锁,我才感觉到都是有套路的,都被玩
这次当我给面试官提及到读写锁的时候,详细问了我的读写锁,我知道怎么回事,用法,但是具体没实践过,听过的还是不要给面试官说了,不然又给自己挖坑。
下面这个程序就是读写锁的程序,分别有两个读者,两个写着,当写着输入end的时候并且读者读到程序运行结束,里面的读写锁是动态初始化,最后用pthread_join(),主要主线程等待子线程运行完她才可以结束。对于现在锁,我才感觉到都是有套路的,都被玩坏了。初始化,处理的,最后是销毁的。此外,我还遇到的一个问题是当时忘记在写线程忘记休眠sleep,结果一直让我写,写,写,那么她就一直拿着cpu写,就算输入end也就结束不了,因为读线程根本执行不到。
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <bits/pthreadtypes.h>
#define WORK_SIZE 1024
static pthread_rwlock_t rwlock;
char work_area[WORK_SIZE];
int time_to_exit;
void *thread_to_read_o(void *arg);
void *thread_to_read_t(void *arg);
void *thread_to_write_o(void *arg);
void *thread_to_write_t(void *arg);
void *thread_to_read_o(void *arg)
{
printf("thread read one try to get lock\n");
pthread_rwlock_rdlock(&rwlock);
while(strncmp("end",work_area,3) != 0){
printf("this is thread read one\n");
printf("the characters is %s\n",work_area);
pthread_rwlock_unlock(&rwlock);
sleep(2);
pthread_rwlock_rdlock(&rwlock);
while(work_area[0] == '\0'){
pthread_rwlock_unlock(&rwlock);
sleep(2);
pthread_rwlock_rdlock(&rwlock);
}
}
pthread_rwlock_unlock(&rwlock);
time_to_exit = 1;
pthread_exit(0);
}
void *thread_to_read_t(void *arg)
{
printf("thread read one try to get lock\n");
pthread_rwlock_rdlock(&rwlock);
while(strncmp("end",work_area,3) != 0){
printf("this is thread read two\n");
printf("the characters is %s\n",work_area);
pthread_rwlock_unlock(&rwlock);
sleep(5);
pthread_rwlock_rdlock(&rwlock);
while(work_area[0] == '\0'){
pthread_rwlock_unlock(&rwlock);
sleep(5);
pthread_rwlock_rdlock(&rwlock);
}
}
pthread_rwlock_unlock(&rwlock);
time_to_exit = 1;
pthread_exit(0);
}
void *thread_to_write_o(void *arg)
{
printf("this is write thread one try to get lock\n");
while(!time_to_exit){
pthread_rwlock_wrlock(&rwlock);
printf("this is write thread one\n,input some text,enter 'end' to finish\n");
fgets(work_area,WORK_SIZE,stdin);
pthread_rwlock_unlock(&rwlock);
sleep(15); // forget sleep,so write always
}
pthread_rwlock_unlock(&rwlock);
pthread_exit(0);
}
void *thread_to_write_t(void *arg)
{
sleep(10);
while(!time_to_exit){
pthread_rwlock_wrlock(&rwlock);
printf("this is write thread two\n input some text,enter 'end' to finish\n");
fgets(work_area,WORK_SIZE,stdin);
pthread_rwlock_unlock(&rwlock);
sleep(20);
}
pthread_rwlock_unlock(&rwlock);
pthread_exit(0);
}
int main(int argc,char *argv[])
{
int retval;
pthread_t a_thread,b_thread,c_thread,d_thread;
void *thread_result;
retval = pthread_rwlock_init(&rwlock,NULL);
if(retval != 0){
// error
exit(1);
}
retval = pthread_create(&a_thread,NULL,thread_to_read_o,NULL);
if(retval != 0){
// error
exit(1);
}
retval = pthread_create(&b_thread,NULL,thread_to_read_t,NULL);
if(retval != 0){
// error
exit(1);
}
retval = pthread_create(&c_thread,NULL,thread_to_write_o,NULL);
if(retval != 0){
// error
exit(1);
}
retval = pthread_create(&d_thread,NULL,thread_to_write_t,NULL);
if(retval != 0){
// error
exit(1);
}
// suspend main thread
pthread_join(a_thread,NULL);
pthread_join(b_thread,NULL);
pthread_join(c_thread,NULL);
pthread_join(d_thread,NULL);
// destroy rwlock
pthread_rwlock_destroy(&rwlock);
printf("main thread will exit\n");
return 0;
}
关于读写锁的第二个程序,主要是测试读锁和写锁哪个更加优先的问题,linux默认的是读者优先
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
pthread_rwlock_t rwlock;
void *readers(void *arg)
{
pthread_rwlock_rdlock(&rwlock);
printf("readers %d got the lock\n",(int)arg);
pthread_rwlock_unlock(&rwlock);
}
void *writes(void *arg)
{
pthread_rwlock_wrlock(&rwlock);
printf("write %d got the lock\n",(int)arg);
pthread_rwlock_unlock(&rwlock);
}
int main(int argc,char *argv[])
{
int retval,i;
pthread_t writer_id,reader_id;
pthread_attr_t attr;
int nreadercount = 1;
int nwritercount = 1;
if(argc != 2){
// error
exit(1);
}
retval = pthread_rwlock_init(&rwlock,NULL);
if(retval != 0){
//error
exit(2);
}
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
// pthread_rwlock_wrlock(&rwlock);
pthread_rwlock_rdlock(&rwlock);
for(i = 0; i < atoi(argv[1]);i++){
if(random() % 2){
pthread_create(&reader_id,&attr,readers,(void *)nreadercount);
printf("create reader %d\n",nreadercount++);
}else{
pthread_create(&writer_id,&attr,writes,(void *)nwritercount);
printf("create writer %d\n",nwritercount++);
}
}
// sleep(10);
pthread_rwlock_unlock(&rwlock);
sleep(10);
return 0;
}
在上面的程序中如果有这个pthread_rwlock_wrlock(&rwlock);那么就算读者先加锁了,这时写者来了,那么再来的读者就不能加锁了,写者一直等到第一个读者结束后自己在加锁。理论是这样的,但是实际的结果,确实有点偏差,先看图
第6个读者先得到了锁,我感觉这个里面做了优化,前9个因为加锁的缘故只能先创建完之后再执行线程,最后一个readers 6,内核已经知道迟早readers 6要执行的,既然内核现在拿着这个reader 6,内核就顺便执行,才不管你有么有pthread_rwlock_wrlock(&rwlock);
在上面的程序中如果有这个pthread_rwlock_rdlock(&rwlock),运行结果
如果有什么问题,欢迎指正
更多推荐
所有评论(0)