请选择 进入手机版 | 继续访问电脑版
设为首页收藏本站

梦织未来

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 935|回复: 2

[交流] 求助一个关于Semaphore信号量机制的问题感激不尽~

[复制链接]

升级   54%

8

主题

0

精华

27

积分
发表于 2017-1-11 22:49:29 | 显示全部楼层 |阅读模式
本帖最后由 xiaogaicai 于 2017-1-11 22:51 编辑

#include "stdafx.h"

#include <Windows.h>

#include <iostream>
using namespace std ;

#include "stdio.h"

#define DEF_DATA_SIZE                128
#define MAX_ACCESS_COUNT        3
#define MAX_THREAD_COUNT        5
#define SEMPHORE_NAME                L"TestSemphore"

BYTE data[DEF_DATA_SIZE] ;
int i=0;
DWORD WINAPI WorkThread ( LPVOID lParam )
{
        // 取得线程索引号
        DWORD dwIndex = *((DWORD*)lParam) ;

        // 打开信标内核对象
        HANDLE hSem = OpenSemaphore ( SEMAPHORE_ALL_ACCESS, FALSE, SEMPHORE_NAME ) ;
        if ( hSem )
        {
                // 等待信标资源
                printf ( "[%d]等待信标资源\n", dwIndex ) ;
                if ( WaitForSingleObject ( hSem, INFINITE ) == WAIT_OBJECT_0 )
                {
                        printf ( "[%d]取得信标资源,可以访问数据!\n", dwIndex ) ;

                        // 到这里,此线程取得数据访问权,假设访问数据data需要3S时间
                        // ……
                i=i+200;
                        Sleep ( 3000 ) ;
                }

                // 释放信标资源
                printf ( "[%d]释放信标资源!\n", dwIndex ) ;
                ReleaseSemaphore ( hSem, 1, NULL ) ;
                CloseHandle ( hSem ) ;
        }
        else
        {
                printf ( "[%d]无法打开信标内核对象!\n", dwIndex ) ;
        }
        return 0 ;
}

int _tmain(int argc, _TCHAR* argv[])
{
        // 初始化数据
        for ( BYTE i = 0; i < DEF_DATA_SIZE; i++ )
                data
= i ;

        // 创建信标内核对象
        HANDLE hSem = CreateSemaphore ( NULL, 0, MAX_ACCESS_COUNT, SEMPHORE_NAME ) ;
        if ( hSem == NULL )
                return 0;

        // 创建工作线程
        DWORD        dwIndex[MAX_THREAD_COUNT] = {0} ;
        HANDLE        hThread[MAX_THREAD_COUNT] = {0} ;
        for ( int i = 0; i < MAX_THREAD_COUNT; i++ )
        {
                dwIndex
= i + 1 ;
                hThread
= CreateThread ( NULL, 0, WorkThread, &dwIndex, 0, NULL ) ;
                if ( hThread
== NULL )
                        return 0 ;
        }

        // Sleep一段时间,使各个工作线程都处于就绪状态
        // 即使所有工作线程都处于等待信标资源的状态
        Sleep ( 2000 ) ;

        // 设置信号量,激活工作线程
        printf ( "设置信号量,激活工作线程\n" ) ;
        ReleaseSemaphore ( hSem, MAX_ACCESS_COUNT, NULL ) ;

        // 等待线程结束
        WaitForMultipleObjects ( MAX_THREAD_COUNT, hThread, TRUE, INFINITE ) ;
        printf ( "所有线程都已经结束!\n" ) ;

        for ( int i = 0; i < MAX_THREAD_COUNT; i++ )
                CloseHandle ( hThread
) ;
        CloseHandle ( hSem ) ;
        return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////代码如上
假设1.2.3线程先得到了3个信号量 那么我想问1.2.3 这3个线程在对全局变量i(我上面代码圈红的)的访问是否是互斥的?会不会造成多个线程去访问一个临界区变量的问题?


回复

使用道具 举报

升级   3.33%

25

主题

2

精华

210

积分
发表于 2017-1-12 10:31:32 | 显示全部楼层
信号量最多可以被获取MAX_ACCESS_COUNT次,再获取(WaitFor)就会开始等待了
所以在你的例子里面那个信号量根本起不到给对变量互斥访问的作用,前三个访问这个变量的线程都能立即获得访问的机会

把Semaphore换成Mutex,或者把MAX_ACCESS_COUNT改成1,才是你想要的互斥访问的效果
回复 支持 反对

使用道具 举报

升级   54%

8

主题

0

精华

27

积分
 楼主| 发表于 2017-1-19 23:05:48 | 显示全部楼层
hzqst 发表于 2017-1-12 10:31
信号量最多可以被获取MAX_ACCESS_COUNT次,再获取(WaitFor)就会开始等待了
所以在你的例子里面那个信号 ...

理解了~感谢前辈
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|Archiver|mengwuji ( 粤ICP备13060035号-1 )  

GMT+8, 2017-11-20 19:37 , Processed in 0.289693 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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