无锁编程(三) - 忙等待

来源:互联网 发布:邢台学院网络教学平台 编辑:程序博客网 时间:2024/05/21 19:21

概念

忙等待可以认为是一种特殊的忙等待

 

忙等待分类

Peterson算法

xchg解法

TSL解法

自旋锁

 

Peterson算法

Peterson算法是一个实现互斥锁的并发程序设计算法,可以控制两个线程访问一个共享的单用户资源而不发生访问冲突。GaryL. Peterson1981年提出此算法。

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <sys/types.h>#include <sys/time.h>#include <stdint.h>int count = 0;#define N 2volatile int turn;   volatile int interested[N] = {0}; void enter_region(int process){int other = 1 - process; //另一个进程  interested[process] = true;turn = process;while (turn == process && interested[other] == true) NULL; //一直循环,直到other进程退出临界区  }void leave_region(int process){interested[process] = false; // leave critical region}void *test_func(void *arg){int process = *((int *)arg);printf("thread %d run\n", process);int i=0;for(i=0;i<2000000;++i){enter_region(process);//printf("%d enter, count = %d\n", pthread_self(),count);++count;leave_region(process);}return NULL;}int main(int argc, const char *argv[]){pthread_t id[N];int process[N];int i = 0;uint64_t usetime;struct timeval start;struct timeval end;gettimeofday(&start,NULL);for(i=0;i<N;++i){process[i] = i;}for(i=0;i<N;++i){pthread_create(&id[i],NULL,test_func,&process[i]);}for(i=0;i<N;++i){pthread_join(id[i],NULL);}gettimeofday(&end,NULL);usetime = (end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);printf("count = %d, usetime = %lu usecs\n", count, usetime);return 0;}

结果说明:

[root@rocket lock-free]#./busywait_peterson 

thread 0 run

thread 1 run

count = 3999851, usetime = 263132 usecs

可以看出,虽然是互斥算法,但是实测的结果缺不是十分精确,有少量的count丢失,这点让人感到很差异,这里先不去深究,有经验的同学可以帮忙分析一下原因。

 

xchg解法

#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <sys/types.h>#include <asm/system.h>#include <sys/time.h>#include <stdint.h>volatile int in_using = 0;int count = 0;#define N 2void enter_region(){while (xchg(&in_using, 1)) NULL;}void leave_region(){in_using = 0;// leave critical region}void *test_func(void *arg){int i=0;for(i=0;i<2000000;++i){enter_region();++count;leave_region();}return NULL;}int main(int argc, const char *argv[]){pthread_t id[20];int i = 0;uint64_t usetime;struct timeval start;struct timeval end;gettimeofday(&start,NULL);for(i=0;i<N;++i){pthread_create(&id[i],NULL,test_func,NULL);}for(i=0;i<N;++i){pthread_join(id[i],NULL);}gettimeofday(&end,NULL);usetime = (end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);printf("count = %d, usetime = %lu usecs\n", count, usetime);return 0;}

结果说明:这个结果自然是非常精确,感觉比peterson算法靠谱多了,性能倒是差别不大。

[root@rocket lock-free]# ./busywait_xchg

count = 4000000, usetime = 166548 usecs

 

TSL解法(Test and Set Lock

enter_region

tsl register, lock |复制lock到寄存器,并将lock置为1

cmp register, #0 | lock等于0?

jne enter_region |如果不等于0,已上锁,再次循环

ret |返回调用程序,进入临界区

 

leave_region

move lock, #0 |lock0

ret |返回调用程序

 

自旋锁

自旋锁请参考我的另一篇文章,这里不再赘述。

http://blog.csdn.net/linux_bug/article/details/48375521



 

0 0
原创粉丝点击