最新帖子 精华区 社区服务 会员列表 统计排行
主题 : Windows核心编程——读书笔记
updowndown 离线
级别: 菜鸟
UID: 1211
精华: 0
发帖: 38
金币: 0 个
银元: 13 个
铜钱: 198 个
技术分: 0 个
在线时间: 16(时)
注册时间: 2011-01-17
最后登录: 2013-03-14
10楼  发表于: 2011-04-03   
对于Window系统开发人员来说,这本书很重要哦。
线程、进程、各种内核对象以及消息机制。
总可以看到你感兴趣的。

这本书对MFC基本没有涉及。所以对多线程有爱的话,使用MFC开发的话,推荐看一下Win32多线程程序设计,看英文版当然最好,中文版是侯捷翻译的,也挺不错。
updowndown 离线
级别: 菜鸟
UID: 1211
精华: 0
发帖: 38
金币: 0 个
银元: 13 个
铜钱: 198 个
技术分: 0 个
在线时间: 16(时)
注册时间: 2011-01-17
最后登录: 2013-03-14
11楼  发表于: 2011-04-11   
关键代码段/临界区的使用

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <process.h>
using namespace std;

/// 关键代码段或是临界区的声明
CRITICAL_SECTION g_cs;

unsigned __stdcall PrintThread1( PVOID pvParm )
{
    /// 当前线程号
    volatile static long lTreadNum = 0;
    int iCurThread = InterlockedIncrement( &lTreadNum );

    for( int i = 0; i < 20; ++ i)
    {
        /// 进入临界区
        EnterCriticalSection(&g_cs);
        /// 对需要保护的资源进行操作
        cout << "线程" << iCurThread << "打印:" << i << endl;
        /// 没此进入临界区后必须调用离开临界区函数
        LeaveCriticalSection(&g_cs);
    }

    return 0;
}

/// 使用TryEnterCriticalSection在获取资源不成功时会立刻返回,这时可以进行一些其它的操作后,再尝试进入
unsigned __stdcall PrintThread2( PVOID pvParm )
{
    volatile static long lTreadNum = 0;
    int iCurThread = InterlockedIncrement( &lTreadNum );

    /// 记录尝试进入临界区的次数
    int iTryEnterTimes = 0;
    for( int i = 0; i < 20; ++ i)
    {
        /// 进入临界区不成功时,尝试次数加1
        while( !TryEnterCriticalSection(&g_cs) )
        {
            ++iTryEnterTimes;
        }
        cout << "线程" << iCurThread << "打印:" << i << "  TryTimes:" << iTryEnterTimes << endl;
        iTryEnterTimes = 0;
        LeaveCriticalSection(&g_cs);
    }

    return 0;
}

/// 启动线程并等待线程返回的函数
void StartThread( unsigned int (__stdcall * ThreadFuc)( void *) )
{
    HANDLE hThread1 = (HANDLE)_beginthreadex(NULL, 0, ThreadFuc, NULL, 0, NULL);
    HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, ThreadFuc, NULL, 0, NULL);

    if( hThread1 != NULL )
    {
        WaitForSingleObject(hThread1, INFINITE);
        CloseHandle(hThread1);
    }

    if( hThread2 != NULL )
    {
        WaitForSingleObject(hThread2, INFINITE);
        CloseHandle(hThread2);
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    /// 在使用临界区前,必须进行初始化
    InitializeCriticalSection(&g_cs);

    StartThread( PrintThread1 );

    cout << endl << endl;

    StartThread( PrintThread2 );

    /// 使用完后,显示删除以避免资源泄漏
    DeleteCriticalSection(&g_cs);

    cout << endl << endl;

    /// 使用旋转锁初始化临界区,可以提高资源使用效率,尽可能使用这种方式进行资源保护
    InitializeCriticalSectionAndSpinCount( &g_cs, 400);
    StartThread( PrintThread1 );
    DeleteCriticalSection(&g_cs);
    return 0;
}
updowndown 离线
级别: 菜鸟
UID: 1211
精华: 0
发帖: 38
金币: 0 个
银元: 13 个
铜钱: 198 个
技术分: 0 个
在线时间: 16(时)
注册时间: 2011-01-17
最后登录: 2013-03-14
12楼  发表于: 2011-04-11   
第9章

1、WaitForSingleObject返回值
    WAIT_ABANDONED 仅有等待对象为mutex时,才有可能返回此值,表示拥有mutex的线程在结束时没有释放核心对象
    WAIT_OBJECT_0    对象已成功激活
    WAIT_TIMEOUT    等待超时
    WAIT_FAILED    出现错误,调用GetLastError得到详细信息
    
2、WaitForMultipleObjects返回值
    当指定等待对象中的某一对象时,返回值除以上值外,可能为WAIT_OBJECT_0到(WAIT_OBJECT_0 + Count - 1)之间的任一值,表示第N个对象被激活


WaitForMultipleObjects与Event的使用
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    /// 创建3个Event对象
    HANDLE hEvent1 = CreateEvent( NULL, ///< 安全属性
                                FALSE,  ///< 是否手动重置对象,为TRUE时等待事件后需手动重置,否则一直处于激发状态
                                NULL,    ///< 是否初始化为激发状态
                                NULL    ///< 名称
                                );
    HANDLE hEvent2 = CreateEvent( NULL, TRUE, NULL, NULL );
    HANDLE hEvent3 = CreateEvent( NULL, FALSE, NULL, NULL );

    HANDLE hObject[3];
    hObject[0] = hEvent1;
    hObject[1] = hEvent2;
    hObject[2] = hEvent3;

    /// 激活所有对象
    SetEvent( hEvent1 );
    SetEvent( hEvent2 );
    SetEvent( hEvent3 );

    /// 等待HANDLE数组中的所有对象,只有所有对象都被激活时才会返回
    DWORD dwResult = WaitForMultipleObjects( 3, hObject, TRUE, INFINITE );
    switch( dwResult )
    {
    case WAIT_OBJECT_0:
        cout << "所有对象都被激活" << endl;
        break;
    case WAIT_FAILED:
        cout << "等待失败" << endl;
        break;
    default:
        break;
    }

    /// 等待成功时,自动重置Event对象会重置Event状态,手动重置则不会,如此时hEvent1、hEvent3已被重置为未激发状态,hEvent2仍处于激发状态
    /// 此时hEvent2已被重置,再次激活
    SetEvent(hEvent3);

    /// 等待多个对象中的某一个时,是按数组由前到后遍历,因此Event2、Event3均被激活的情况下,等待到的事件为Event2
    dwResult = WaitForMultipleObjects( 3, hObject, FALSE, INFINITE );
    switch( dwResult )
    {
    case WAIT_OBJECT_0:
        cout << "hEvent1被激活" << endl;
        break;
    case WAIT_OBJECT_0 + 1:
        cout << "hEvent2被激活" << endl;
        break;
    case WAIT_OBJECT_0 + 2:
        cout << "hEvent3被激活" << endl;
        break;
    case WAIT_FAILED:
        cout << "等待失败" << endl;
        break;
    default:
        break;
    }

    /// 手动重置Event对象
    ResetEvent(hEvent2);

    /// 再次等待,Event2处于未激发状态,等待到的事件为Event3
    dwResult = WaitForMultipleObjects( 3, hObject, FALSE, INFINITE );
    switch( dwResult )
    {
    case WAIT_OBJECT_0:
        cout << "hEvent1被激活" << endl;
        break;
    case WAIT_OBJECT_0 + 1:
        cout << "hEvent2被激活" << endl;
        break;
    case WAIT_OBJECT_0 + 2:
        cout << "hEvent3被激活" << endl;
        break;
    case WAIT_FAILED:
        cout << "等待失败" << endl;
        break;
    default:
        break;
    }

    /// 释放内核对象
    CloseHandle(hEvent1);
    CloseHandle(hEvent2);
    CloseHandle(hEvent3);

    return 0;
admin 离线
级别: 管理员
UID: 1
精华: 1
发帖: 994
金币: 526 个
银元: 488 个
铜钱: 7838 个
技术分: 601 个
在线时间: 736(时)
注册时间: 2010-04-21
最后登录: 2018-01-19
13楼  发表于: 2011-04-26   
很不错啊
描述
快速回复

如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
认证码:

验证问题:
printf("%d", 113)
按"Ctrl+Enter"直接提交