鱼C论坛

 找回密码
 立即注册
查看: 4589|回复: 6

win7和xp下临界区CriticalSection的问题

[复制链接]
发表于 2013-6-3 20:57:04 | 显示全部楼层 |阅读模式
2鱼币
本帖最后由 fanki 于 2013-6-7 22:02 编辑

同样的代码,不同的结果,xp可以跑出想要的效果,可是win7下不能,求说明win7为什么会这样输出?想知道真相,谢谢
代码如下:

头文件没有改动,创建的是控制台,简单的。

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
CRITICAL_SECTION cs = { 0 };
DWORD CALLBACK TestProc1( LPVOID pParam )
{
        //for ( int i = 0; i < 10; i++ )
        while( 1 )
        {
                EnterCriticalSection( &cs );
                printf( "********\n" );
                Sleep( 100 );
                LeaveCriticalSection( &cs );
        }
        return 0;
}
DWORD CALLBACK TestProc2( LPVOID pParam )
{
        //for ( int i = 0; i < 10; i++ )
        while( 1 )
        {
                EnterCriticalSection( &cs );
                printf( "--------\n" );
                Sleep( 100 );
                LeaveCriticalSection( &cs );
        }
        return 0;
}
int main(int argc, char* argv[])
{
        InitializeCriticalSection( &cs );
        DWORD nID = 0;
        HANDLE hThread[2] = { 0 };
        hThread[0] = CreateThread( NULL, 0, TestProc1, NULL,
                                        0, &nID );
        hThread[1] = CreateThread( NULL, 0, TestProc2, NULL,
                                        0, &nID );
        WaitForMultipleObjects( 2, hThread, TRUE, INFINITE );
        CloseHandle( hThread[0] );
        CloseHandle( hThread[1] );
        DeleteCriticalSection( &cs );
        return 0;
}

谢谢大家帮助,我想和大家一起学得更多,更好。


最佳答案

查看完整内容

临界区具有“线程拥有权”的概念,因此,第一段代码可以连续进入5次临界区,再让第二段代码进入。临界区只能保证上面两段代码的互斥关系,不能保证两段代码的执行顺序。要保证执行顺序应该使用事件或信号量。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-6-3 20:57:05 | 显示全部楼层
临界区具有“线程拥有权”的概念,因此,第一段代码可以连续进入5次临界区,再让第二段代码进入。临界区只能保证上面两段代码的互斥关系,不能保证两段代码的执行顺序。要保证执行顺序应该使用事件或信号量。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-6-4 11:58:46 | 显示全部楼层
强烈支持楼主ing……
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-6-4 19:02:08 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-25 22:43:21 | 显示全部楼层
                  没咋看懂,不过希望以后能和大家在鱼C里一起学习!!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-26 10:33:26 | 显示全部楼层
这个跟系统调度有关,你可以把Sleep(100); 这句代码放到LeaveCriticalSection( &cs ); 后面就正常了。

大体是这样的, 你在线程1中先进入临界区, 打印,然后Sleep(),Sleep的时候,系统会放弃执行该线程。转而去执行线程2,但是由于线程1进入临界区还没返回,所以线程2只能等待,所以系统会放弃线程2 的执行,转而执行线程1,线程1睡完了,执行离开临界区的操作。这时很关键了,如果线程1的时间片刚好用完,那么系统会执行线程2,如果没用完,则继续执行该线程,又一次进入了临界区,如此往复。所以只看到一个线程在不停的打印。另外一个线程得不到执行的机会。

至于xp下的情况我没测试,原理也一样。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-26 23:11:02 | 显示全部楼层
编程难 发表于 2013-7-26 10:33
这个跟系统调度有关,你可以把Sleep(100); 这句代码放到LeaveCriticalSection( &cs ); 后面就正常了。

...

谢谢哇~~~我去试试~~又什么不懂再问问你吧~~{:7_155:}
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-26 23:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表