zoukankan      html  css  js  c++  java
  • Interlocked系列函数线程同步的缺陷

    1、 Code

    int	Work()
    {
    	while (m_lInterlockedData < 10)
    	{
    		InterlockedIncrement(&m_lInterlockedData);			
    		Sleep(100);
    	}
    
    	printf("CInterlocked::Work end
    ");
    
    	return	0;
    }
    5个线程运行Work()函数,理论上m_lInterlockedData最后运行的结果应该是10
    BOOL	RunThread()
    {
    	CloseHandle((HANDLE)_beginthreadex(NULL, NULL, ThreadProc, this, NULL, NULL));
    	CloseHandle((HANDLE)_beginthreadex(NULL, NULL, ThreadProc, this, NULL, NULL));
    	CloseHandle((HANDLE)_beginthreadex(NULL, NULL, ThreadProc, this, NULL, NULL));
    	CloseHandle((HANDLE)_beginthreadex(NULL, NULL, ThreadProc, this, NULL, NULL));
    	CloseHandle((HANDLE)_beginthreadex(NULL, NULL, ThreadProc, this, NULL, NULL));
    
    	return	TRUE;
    }

    2、 运行结果

    实际运行结果却令人意外,m_lInterlockedData = 11, why?
    3、 原因
    做以下假设:
    3.1 m_lInterlockedData = 9时,线程运行完while(m_lInterlockedData < 10) ,会判断为真。
    3.2 此时系统切换到线程运行,线程2Work函数会将m_lInterlockedData增加到10
    3.3 系统再次切换返回到线程1运行,由于while的判定代码已执行且为真,所以此时会执行InterlockedIncrement(&m_lInterlockedData);从而将m_lInterlockedData再次增加到11
    4、 解决方法
    改用临界区即可解决如上问题
    int	WorkEx()
    {
    	while (TRUE)
    	{
    		EnterCriticalSection(&m_cs);
    		if (m_lInterlockedData < 10)
    		{
    			m_lInterlockedData++;
    			LeaveCriticalSection(&m_cs);
    		}
    		else
    		{
    			LeaveCriticalSection(&m_cs);
    			break;
    		}
    		
    		Sleep(100);
    	}
    	
    	printf("CInterlocked::Work end
    ");
    	
    	return	0;
    }

    注意,为了不让在临近区中等待过久,故将Sleep(100) 放在LeaveCriticalSection() 之外。

    本文为博主原创文章,如需转载请说明转至http://www.cnblogs.com/organic/
  • 相关阅读:
    关闭Pinterest通知
    android——创建camera应用(译)
    Android样式——Styles
    Android Fragment学习(一)
    Win32汇编环境配置
    关于微信检测SDK应用的原理浅析(iOS)
    iOS的Mantle实战
    Objective-C运行时的一些技巧
    Autolayout入门教程
    基于RAC的通用TableView
  • 原文地址:https://www.cnblogs.com/organic/p/5005651.html
Copyright © 2011-2022 走看看