• 无锁编程(三)


    概念

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

     

    忙等待分类

    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 2
    volatile 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
    ", process);
    	int i=0;
    	for(i=0;i<2000000;++i)
    	{
    		enter_region(process);
    		//printf("%d enter, count = %d
    ", 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
    ", 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 2
    
    void 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
    ", 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://www.cnblogs.com/linuxbug/p/4840152.html

     版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    Discuz X 2.5 点点(伪静态)
    jq 、xml 省市级联动
    php memcache 初级使用(2)
    关于windows虚拟内存管理的页目录自映射
    SharePoint 2010 网络上的开发经验和资源
    SharePoint 2010 Reporting Services 报表服务器正在内置 NT AUTHORITY\SYSTEM 账户下运行 解决方法
    SharePoint 2010 Reporting Services 报表服务器无法解密用于访问报表服务器数据库中的敏感数据或加密数据的对称密钥 解决方法
    Active Directory Rights Management Services (AD RMS)无法检索证书层次结构。 解决方法
    SharePoint 2010 Reporting Services 报表服务器实例没有正确配置 解决方法
    SharePoint 2010 页面引用 Reporting Services 展现 List 报表
  • 原文地址:https://www.cnblogs.com/linuxbug/p/4840143.html
Copyright © 2020-2023  润新知