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/
  • 相关阅读:
    ajax学习笔记
    CSS3伪类
    《HTML5与CSS3基础教程》学习笔记 ——Four Day
    《HTML5与CSS3基础教程》学习笔记 ——Three Day
    《HTML5与CSS3基础教程》学习笔记 ——Two Day
    《HTML5与CSS3基础教程》学习笔记 ——One Day
    js面向对象笔记
    《锋利的jQuery》心得笔记--Four Sections
    《锋利的jQuery》心得笔记--Three Sections
    《锋利的jQuery》心得笔记--Two Sections
  • 原文地址:https://www.cnblogs.com/organic/p/5005651.html
Copyright © 2011-2022 走看看