亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲(chóng)蟲(chóng)下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲(chóng)蟲(chóng)下載站

?? cbroadcast.cpp

?? window下的多線程編程參考書(shū)。值得一讀
?? CPP
字號(hào):
#include "CMcl.h"
#include <stdio.h>
#include <assert.h>

class CBroadcastChannel {
private:
    enum { MAX_CLIENTS = 32 };

    typedef struct {
        DWORD dwClientMask;
        BYTE abData[1];    
    } SampleHeader;

private:
    DWORD m_dwMaxSamples;
    DWORD m_cbDataSize;
    DWORD m_cbSampleSize;
    SampleHeader *m_pSample;
    DWORD m_dwNextWrite;
    DWORD m_adwNextRead[MAX_CLIENTS];
    DWORD m_dwClientMask;
    CMclSemaphore m_csBuffersEmpty;    
    CMclSemaphoreAutoPtr m_apcsBuffersFull[MAX_CLIENTS];
    CMclMutex m_cmUpdateGuard;

public:
    CBroadcastChannel( DWORD dwMaxSamples, DWORD cbDataSize) : 
                m_csBuffersEmpty( dwMaxSamples, dwMaxSamples),
                m_cmUpdateGuard() {
        m_dwMaxSamples = dwMaxSamples;
        m_cbDataSize = cbDataSize;
        m_cbSampleSize = cbDataSize + sizeof(SampleHeader) - 1;
        m_pSample = (SampleHeader *) new BYTE[m_cbSampleSize * m_dwMaxSamples];
        ZeroMemory( m_pSample, m_cbSampleSize * m_dwMaxSamples);
        m_dwClientMask = 0;
        m_dwNextWrite = 0;
        ZeroMemory( m_adwNextRead, sizeof(DWORD) * MAX_CLIENTS);
    };

    DWORD Register(void) {
        // grab the guard mutex...
        CMclAutoLock lock(m_cmUpdateGuard);

        // find the next available ID,
        // MAX_CLIENTS ID's are available, at each bit position
        // of a DWORD...
        for (DWORD dwMask = 1, dwId = 0; dwMask; dwMask <<= 1, dwId++) {
            if (!(dwMask & m_dwClientMask)) {
                // mark the bit in the client mask...
                m_dwClientMask |= dwMask;

                // allocate a semaphore...
                m_apcsBuffersFull[dwId] = new CMclSemaphore( 0, m_dwMaxSamples);

                // reading will start with the NEXT sample written
                // into the broadcast channel...
                m_adwNextRead[dwId] = m_dwNextWrite;

                // return the id...
                return dwId;
            }
        }

        // return 0xFFFFFFFF if we are servicing
        // the maximum number of clients...
        return 0xFFFFFFFF;
    };

    void Unregister(DWORD dwId) {
        // grab the guard mutex...
        CMclAutoLock lock(m_cmUpdateGuard);

        // remove this client from all of the samples...        
        DWORD dwSample;
        DWORD dwReleaseCount = 0;
        DWORD dwMask = 1 << dwId;
        for (dwSample = 0; dwSample < m_dwMaxSamples; dwSample++) {
            SampleHeader *pNextSample = (SampleHeader *) ((LPBYTE)m_pSample + m_cbSampleSize * dwSample);
            if (pNextSample->dwClientMask & dwMask) {
                pNextSample->dwClientMask &= ~dwMask;
                if (pNextSample->dwClientMask == 0) {
                    // this sample has no waiting clients
                    // and can be freed...
                    dwReleaseCount++;
                }
            }

        }

        // release the semaphore equal to the number
        // of samples freed...
        if (dwReleaseCount > 0) {
            m_csBuffersEmpty.Release(dwReleaseCount);
        }

        // zero out the bit for this client ID...
        m_dwClientMask &= ~dwMask;
    };

    BOOL ReadSample( DWORD dwId, LPVOID pSample) {
        // compute the semaphore index from the id
        // and wait until some buffers are ready to be read...
        m_apcsBuffersFull[dwId]->Wait(INFINITE);
        
        // read the next sample for this client...
        DWORD dwSample = m_adwNextRead[dwId];
        SampleHeader *pNextSample = (SampleHeader *) ((LPBYTE)m_pSample + m_cbSampleSize * dwSample);

        DWORD dwMask = 1 << dwId;
        if (pNextSample->dwClientMask & dwMask) {
            // found a sample, copy out the data...
            // this sample can be read by multiple
            // clients at the same time...
            CopyMemory( pSample, pNextSample->abData, m_cbDataSize);

            // now we need to modify and check the client
            // mask for this same, so we must acquire the
            // guard mutex...
            m_cmUpdateGuard.Wait(INFINITE);

            // mark the sample as read by this client...
            pNextSample->dwClientMask &= ~dwMask;

            // release this sample if everyone has read it...
            if (pNextSample->dwClientMask == 0) {
                m_csBuffersEmpty.Release(1);
            }

            // increment the read pointer...
            m_adwNextRead[dwId] = (m_adwNextRead[dwId] + 1) % m_dwMaxSamples;

            // release the guard mutex...
            m_cmUpdateGuard.Release();

            // return success...
            return TRUE;
        }

        // something went wrong...
        return FALSE;
    };

    BOOL WriteSample( LPVOID pSample) {
        // wait for a empty sample buffer to become available...
        // we will be modifying the sample so we
        // need to acquire the guard mutex as well...
        m_csBuffersEmpty.WaitForTwo( m_cmUpdateGuard, TRUE, INFINITE);

        // only broadcast this sample if there are clients...
        BOOL bSampleWritten;
        if (m_dwClientMask) {
            // compute the pointer to the next sample...
            SampleHeader *pNextSample = (SampleHeader *) ((LPBYTE)m_pSample + m_cbSampleSize * m_dwNextWrite);
        
            // set all the current client bits...
            pNextSample->dwClientMask = m_dwClientMask;

            // copy the data into the sample...
            CopyMemory( pNextSample->abData, pSample, m_cbDataSize);

            // increment the write index...
            m_dwNextWrite = (m_dwNextWrite + 1) % m_dwMaxSamples;

            // increase the semaphore counts of all the readers...
            DWORD dwIndex;
            DWORD dwMask;
            for (dwIndex = 0, dwMask = 1; dwIndex < MAX_CLIENTS; dwMask <<= 1, dwIndex++) {
                if (m_dwClientMask & dwMask)
                    m_apcsBuffersFull[dwIndex]->Release(1);
            }

            bSampleWritten = TRUE;
        }
        else {
            // throw away the sample, release the buffer...
            m_csBuffersEmpty.Release(1);
            bSampleWritten = FALSE;
        }

        // release the guard mutex...
        m_cmUpdateGuard.Release();

        // return status indicates if sample was written...
        return bSampleWritten;
    };
};

class MultiConsumerHandler : public CMclThreadHandler {
private:
    CMclThreadAutoPtr m_apThread;
    BOOL m_bRun;
    CBroadcastChannel *m_pBroadcast;
    DWORD m_dwId;

public:
    MultiConsumerHandler( CBroadcastChannel *pBroadcast) {
        m_bRun = TRUE;
        m_pBroadcast = pBroadcast;
        m_apThread = new CMclThread(this);
    };

    void Stop(void) {
        m_bRun = FALSE;
        m_apThread->Wait(INFINITE);
    };

    unsigned ThreadHandlerProc(void) {
        // register with the broadcast channel
        // before we read from it...
        m_dwId = m_pBroadcast->Register();

        printf( "Consumer #%d Started.\n", m_dwId);

        while (m_bRun) {
            DWORD dwSample;
            BOOL bStatus = m_pBroadcast->ReadSample( m_dwId, &dwSample);
            assert(bStatus);
            printf( "Handler ID=%d has read sample <%d>.\n", m_dwId, dwSample);
            Sleep(m_dwId*100);
        }

        // unregister when we are done with the
        // broadcast channel...
        m_pBroadcast->Unregister(m_dwId);

        printf( "Consumer #%d Stopped.\n", m_dwId);

        return 0;
    };
    
};

class ProducerHandler : public CMclThreadHandler {
private:
    CMclThreadAutoPtr m_apThread;
    BOOL m_bRun;
    CBroadcastChannel *m_pBroadcast;

public:
    ProducerHandler( CBroadcastChannel *pBroadcast) {
        m_bRun = TRUE;
        m_pBroadcast = pBroadcast;
        m_apThread = new CMclThread(this);
    };

    void Stop(void) {
        m_bRun = FALSE;
        m_apThread->Wait(INFINITE);
    };

    unsigned ThreadHandlerProc(void) {
        printf( "Producer Started.\n");

        DWORD dwData = 0;
        while (m_bRun) {
            // write data into the broadcast channel
            // until we are told to stop...
            m_pBroadcast->WriteSample( &dwData);
            dwData++;
        }

        printf( "Producer Stopped.\n");
        
        return 0;
    }
};

// define some constants for the main() function.,.
#define NUMBER_CONSUMERS 8
#define NUMBER_CHANNEL_BUFFERS 4

int main( int argc, char *argv[]) {
    CBroadcastChannel broadcast( NUMBER_CHANNEL_BUFFERS, sizeof(DWORD));
    ProducerHandler *pProducer;
    MultiConsumerHandler *pConsumer[NUMBER_CONSUMERS];
    
    // create the producer...
    printf("Creating the Producer...\n");
    pProducer = new ProducerHandler( &broadcast);

    // create nConsumers consumers...
    int i;
    for (i = 0; i < NUMBER_CONSUMERS; i++) {
        printf( "Creating Consumer #%d...\n", i);
        pConsumer[i] = new MultiConsumerHandler( &broadcast);
    }

    // let everything run for a little while...
    Sleep(2000);

    // stop the consumers...
    for (i = 0; i < NUMBER_CONSUMERS; i++) {
        printf( "Stopping Consumer #%d...\n", i);
        pConsumer[i]->Stop();
        delete pConsumer[i];
    }

    // stop the producer...
    printf("Stopping the Producer...\n");
    pProducer->Stop();
    delete pProducer;

    // all done...
    printf("Exiting.\n");
    return 0;
}


?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
a亚洲天堂av| 裸体歌舞表演一区二区| av一区二区久久| 亚洲欧美自拍偷拍| 色婷婷av一区| 亚洲成人一区在线| 欧美一级xxx| 国产精品夜夜爽| 亚洲色图在线看| 欧美精品粉嫩高潮一区二区| 久久精品国产成人一区二区三区| 久久在线免费观看| 99精品视频中文字幕| 亚洲第四色夜色| 日韩一区二区三区在线视频| 国产成人精品免费一区二区| 亚洲欧美日韩国产手机在线| 7799精品视频| 成人永久看片免费视频天堂| 亚洲卡通欧美制服中文| 日韩一级成人av| 成人午夜大片免费观看| 亚洲v中文字幕| 国产亚洲精品bt天堂精选| 99久久国产免费看| 日一区二区三区| 中文字幕成人网| 欧美日韩一区小说| 国产成人av一区二区| 亚洲国产美国国产综合一区二区| 日韩午夜三级在线| 91国内精品野花午夜精品| 久久国产人妖系列| 一区二区三区四区不卡视频| 欧美成人激情免费网| 色天天综合色天天久久| 激情六月婷婷综合| 亚洲成人动漫精品| 国产精品美女久久久久久久网站| 制服视频三区第一页精品| jiyouzz国产精品久久| 青青国产91久久久久久| 亚洲免费观看高清| 国产视频一区在线观看| 欧美一区二区三区免费在线看 | 蜜臀久久99精品久久久久久9| 中文字幕在线播放不卡一区| 日韩欧美第一区| 欧美色男人天堂| 成人av午夜影院| 黄一区二区三区| 美女视频网站黄色亚洲| 一区二区在线看| 国产精品传媒在线| 久久男人中文字幕资源站| 欧美军同video69gay| 91香蕉视频在线| 从欧美一区二区三区| 久久精品国产999大香线蕉| 亚洲成年人影院| 一区二区三区免费在线观看| 中文字幕中文字幕在线一区 | 亚洲国产精品久久不卡毛片| 国产精品久久久久久久久免费桃花| 欧美成人a视频| 91精品国产欧美一区二区18| 在线电影欧美成精品| 欧美日韩亚洲综合在线| 色综合久久综合中文综合网| 99精品视频在线观看免费| 国产成人一区在线| 国产成人综合亚洲91猫咪| 狠狠色丁香婷婷综合| 国产在线视频精品一区| 黑人巨大精品欧美一区| 国产精品资源在线观看| 国产伦理精品不卡| 成人影视亚洲图片在线| 成人高清在线视频| 99久久精品国产一区| 日本高清成人免费播放| 欧美性大战xxxxx久久久| 欧美性猛交xxxxxx富婆| 在线播放亚洲一区| 日韩一级免费一区| 久久综合九色综合97婷婷| 2024国产精品视频| 中文字幕第一区| 亚洲欧美国产高清| 亚洲成人动漫av| 麻豆成人免费电影| 韩国三级电影一区二区| 粉嫩一区二区三区性色av| 波多野结衣视频一区| 91久久香蕉国产日韩欧美9色| 欧美专区在线观看一区| 欧美一区二区福利在线| 久久久精品欧美丰满| 中文字幕日韩一区| 亚洲成人在线网站| 国产在线国偷精品产拍免费yy| 成人国产在线观看| 欧美日韩高清不卡| 欧美精品一区二区三区蜜桃 | 国产九九视频一区二区三区| 成人免费看的视频| 欧美日韩一级片网站| 久久你懂得1024| 亚洲综合成人在线视频| 蜜臀av在线播放一区二区三区| 国产白丝网站精品污在线入口| 99久久久久免费精品国产 | 精品88久久久久88久久久| 中文字幕av一区二区三区免费看 | 国产精品高清亚洲| 丝瓜av网站精品一区二区| 国产精品一二三四区| 91国偷自产一区二区三区观看| 欧美一区永久视频免费观看| 国产精品婷婷午夜在线观看| 亚洲高清在线精品| 成人午夜免费视频| 91精品国产综合久久精品| 国产精品国产三级国产普通话99 | 91精品国产欧美日韩| 国产精品色哟哟| 日韩高清一区在线| www.色综合.com| 日韩欧美不卡一区| 亚洲一区二区欧美日韩| 激情丁香综合五月| 884aa四虎影成人精品一区| 国产精品免费视频一区| 蜜臀精品一区二区三区在线观看| 99国产欧美久久久精品| 久久蜜桃一区二区| 日日欢夜夜爽一区| 99久久99久久综合| 国产网站一区二区三区| 青椒成人免费视频| 欧美中文字幕一二三区视频| 国产精品久久网站| 国产一区二区三区精品视频| 91精品国产入口在线| 亚洲午夜一区二区| 91视频在线看| 国产精品国产精品国产专区不蜜| 国产在线乱码一区二区三区| 91麻豆精品国产自产在线 | 欧美刺激脚交jootjob| 一区二区三区四区国产精品| www.66久久| 国产欧美一区二区三区鸳鸯浴| 强制捆绑调教一区二区| 欧美顶级少妇做爰| 午夜精品免费在线| 欧美亚洲动漫制服丝袜| 一个色在线综合| 色综合久久综合网欧美综合网| 中文字幕一区二区三区在线播放 | av资源站一区| 欧美精彩视频一区二区三区| 国产专区综合网| 久久日韩粉嫩一区二区三区| 狠狠色综合日日| 久久久精品综合| 成人国产精品免费观看视频| 国产精品护士白丝一区av| 成人97人人超碰人人99| 综合久久一区二区三区| 色综合天天性综合| 亚洲综合另类小说| 777午夜精品视频在线播放| 日韩影院精彩在线| 日韩一本二本av| 国产精品一区二区三区四区| 中文av一区特黄| 色综合色综合色综合色综合色综合 | 不卡的av电影| 亚洲色图清纯唯美| 欧美三级中文字幕| 日本不卡在线视频| 久久亚洲春色中文字幕久久久| 国内久久精品视频| 国产精品美女久久久久久| 色呦呦一区二区三区| 亚洲一区二区欧美日韩| 日韩免费一区二区三区在线播放| 国模冰冰炮一区二区| 中文字幕视频一区| 欧美另类变人与禽xxxxx| 久久精品国产精品亚洲精品| 中文字幕欧美三区| 日本精品一区二区三区四区的功能| 午夜久久久久久电影| 久久久综合精品| 欧洲日韩一区二区三区| 久久www免费人成看片高清| 国产精品你懂的在线欣赏| 欧美日韩一区二区三区在线看|