• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            我住包子山

            this->blog.MoveTo("blog.baozishan.in")

            翻譯一篇文章Introduction to Multi-threaded Code 多線程編程的一些代碼 已經(jīng)全譯好了

            Someone recently asked me what I recommend for synchronizing worker threads and I suggested setting an event. This person's response was that you could not do that since worker threads do not support a message pump (UI threads are required to support messages). The confusion here is that events and messages are different animals under windows.

            我忘記了我從哪里copy的這些例子代碼,他們可是非常簡單而有趣的。如果有人知道這些代碼的作者,我一定要好好感謝你和這位作者。

            注意這里有很多對于沒有提及的MFC的支持。像_beginthread(一個C運行時庫調(diào)用)的API可以在MFC應(yīng)用程序中替換成AfxBeginThread

            無同步(No Synchronization)

            這第一個例子描述了兩個互不同步的線程。進程中的首要線程--主函數(shù)循環(huán),輸出全局整形數(shù)組的內(nèi)容。還有一個線程“Thread”不停的給數(shù)組每個元素+1。
            ?The thread called "Thread" continuously populates the global array of integers.

            				  #include <process.h>
            				  #include <stdio.h>
            				int a[ 5 ];
              
              void Thread( void* pParams )
              { int i, num = 0;
              
                while ( 1 )
                { 
                   for ( i = 0; i < 5; i++ ) a[ i ] = num;
                   num++;
                }
              }
              
              int main( void )
              { 
                 _beginthread( Thread, 0, NULL );
              
                 while( 1 )
                    printf("%d %d %d %d %d\n", 
                           a[ 0 ], a[ 1 ], a[ 2 ],
                           a[ 3 ], a[ 4 ] );
              
               return0;
              }
            

            注意這個例子的輸出,紅色的數(shù)處在一個主線程搶先于Thread工作過程中執(zhí)行的打印動作

            81751652 81751652 81751651 81751651 81751651
            81751652 81751652 81751651 81751651 81751651
            83348630 83348630 83348630 83348629 83348629
            83348630 83348630 83348630 83348629 83348629
            83348630 83348630 83348630 83348629 83348629

            ?

            關(guān)鍵區(qū)域/臨界區(qū)域 對象(Critical Section Objects)

            如果你想讓主線程等待Thread線程處理好全局數(shù)組再做打印,一種解決方法是使用關(guān)鍵區(qū)域?qū)ο蟆?br />關(guān)鍵區(qū)域對象提供同步于使用互斥器(Mutex)對象很相似, 除了關(guān)鍵區(qū)域?qū)ο笾茉谝粋€進程內(nèi)發(fā)揮效用。Event, mutex,?以及 semaphore?對象也可以用在單進程的應(yīng)用程序中, 但是關(guān)鍵區(qū)域?qū)ο筇峁┮粋€相對快捷更加高效的同步機制. 就像互斥器一樣, 一個關(guān)鍵區(qū)域?qū)ο笾荒芡瑫r被一個線程擁有, 這個關(guān)鍵區(qū)域能夠在同時發(fā)生的數(shù)據(jù)存取時保護共享資源. 獲取關(guān)鍵區(qū)域的先后順序不定,可是不用太擔(dān)心,系統(tǒng)對于每一個線程都是平等的。

            ???  
              CRITICAL_SECTION cs;
              int a[ 5 ];
              
              void Thread( void* pParams )
              {
                int i, num = 0;
              
                while ( TRUE )
                {
                   EnterCriticalSection( &cs );
                   for ( i = 0; i < 5; i++ ) a[ i ] = num;
                   LeaveCriticalSection( &cs );
                   num++;
                }
              }
              
              int main( void )
            { InitializeCriticalSection( &cs ); _beginthread( Thread, 0, NULL ); while( TRUE ) { EnterCriticalSection( &cs ); printf( "%d %d %d %d %d\n", a[ 0 ], a[ 1 ], a[ 2 ], a[ 3 ], a[ 4 ] ); LeaveCriticalSection( &cs ); } return 0; }

            If you are running Windows 9x/NT/2000, you can run this program by clicking here.

            互斥器(Mutex Objects)

            一個互斥器是一個信號狀態(tài)的同步對象,當(dāng)它不屬于任何一個線程時就用信號來體現(xiàn),當(dāng)被擁有時他的信號狀態(tài)就為None. 同一時刻只有一個線程可以擁有互斥器, 互斥器這個名字來自于他們對于并列的線程存取共享資源時表現(xiàn)出的行為。舉個例子,避免兩個線程同時寫入一個共享內(nèi)存,每一個線程當(dāng)需要執(zhí)行存取共享資源的代碼時首先等待直到自己獲得擁有權(quán). 在存取共享資源之后,線程釋放對互斥器的擁有權(quán)。

            兩個或以上的進程可以調(diào)用CreateMutex 來建立同樣名字的互斥器. 實際上第一個進程建立的這個互斥器, 隨后的進程只是得到了那個存在的互斥器的句柄. 這能使多進程共用一個互斥器, 當(dāng)然用戶應(yīng)該有確保建立互斥器的進程首先啟動的責(zé)任. 使用這種技術(shù),你應(yīng)該將這個 bInitialOwner標(biāo)記設(shè)置成FALSE; 否則, 它可以因不同的進程最初擁有它而帶來困難.

            多進程可以有同一個mutex對象的句柄, 讓mutex對象能夠用于多進程間同步. 下面的對象共享機制是適用的:

            • 一個子進程通過CreateProcess?函數(shù)被建立,當(dāng)CreateMutex的lpMutexAttributes?參數(shù)給予相應(yīng)的mutex對象指針?biāo)梢岳^承到一個mutex對象的句柄.
            • 一個進程可以在DuplicateHandle 函數(shù)中指定一個mutex對象句柄來建立一個句柄的拷貝由其他進程使用.
            • 一個繼承可以指定一個mutex的名字通過 CreateMutex 函數(shù)得到這個mutex對象的句柄.

            總的來說, 如果你想要進行線程同步,臨界區(qū)域更高效些.

            				#include <windows.h>
            				#include <process.h>
            				#include <stdio.h>
              
              HANDLE hMutex;
              int a[ 5 ];
              
              void Thread( void* pParams )
              { 
                 int i, num = 0;
              
                 while ( TRUE )
                 { 
                    WaitForSingleObject( hMutex, INFINITE );
                    for ( i = 0; i < 5; i++ ) a[ i ] = num;
                    ReleaseMutex( hMutex );
                    num++;
                 }
              }
              
              int main( void )
              {
                 hMutex = CreateMutex( NULL, FALSE, NULL );
                 _beginthread( Thread, 0, NULL );
              
                 while( TRUE )
            { WaitForSingleObject( hMutex, INFINITE ); printf( "%d %d %d %d %d\n", a[ 0 ], a[ 1 ], a[ 2 ], a[ 3 ], a[ 4 ] ); ReleaseMutex( hMutex ); } return0; }

            If you are running Windows 9x/NT/2000, you can run this program by clicking here.

            Event Objects事件對象

            若我們想要強制第二線程在主線程完成全局數(shù)組的內(nèi)容輸出時執(zhí)行該如何?這樣的話每行的輸出就只是遞增1。

            一個事件對象也是一個可以通過SetEvent or PulseEvent 函數(shù)設(shè)置像信號般的狀態(tài)的同步對象. 下面是兩種類型的事件對象.

            Object Description
            Manual-reset event
            手動激發(fā)對象
            只有使用ResetEvent 函數(shù)才可以將其設(shè)置為無激發(fā)狀態(tài). 當(dāng)它在激發(fā)狀態(tài)時, 它會激發(fā)所有正在等待的線程, 執(zhí)行對相同 event對象的線程會立即從wait函數(shù)返回.
            Auto-reset event
            自動激發(fā)對象
            一個只相應(yīng)一個線程的wait函數(shù)的事件對象(當(dāng)這個對象是激發(fā)狀態(tài)),wait函數(shù)返回同時事件對象自動變成無激發(fā)狀態(tài)?,當(dāng)沒有線程執(zhí)行wait事件對象仍然是激發(fā)狀態(tài).

            event object的用處就在于它可以在它發(fā)生時向等待著的線程發(fā)出信號標(biāo)志從而使其wait結(jié)束.?舉個例子, 在overlapped I/O 操作時, 當(dāng)異步操作完成時系統(tǒng)設(shè)置了那個由程序員指定(specified)的事件對象為信號狀態(tài). A 一個單一線程可以指定許多不同的事件對象在許多同時發(fā)生的overlapped 操作運作, 調(diào)用一個多對象的wait函數(shù)可以當(dāng)任意一個event object激發(fā)時結(jié)束等待.

            在一個線程中可使用 CreateEvent 函數(shù)建立一個event object. 在這個線程中指定這個event object 的特性是manual-reset?或者 auto-reset . 在這個線程中也可以命名一個event object. 其他進程中的線程也可以使用 OpenEvent 通過event object的名字打開一個現(xiàn)存event object . 另外關(guān)于mutex, event, semaphore, 以及 timer objects的其他信息, 就參考《Interprocess Synchronization》的文章.

            一個線程能夠用 PulseEvent?函數(shù)設(shè)置一個event?object 為信號狀態(tài)而后激發(fā)當(dāng)前適當(dāng)數(shù)量的wait線程,之后切換為無信號狀態(tài) .?對于一個manual-reset event object, 所有的等待線程被返回(release). 對于一個auto-reset event object, 這個函數(shù)只能釋放一個等待的線程, 即使有更多線程在等待. 如果沒有線程在函數(shù)調(diào)用時等待, PulseEvent 只是簡單的將事件狀態(tài)設(shè)為無信號并且返回(個人注釋,這應(yīng)該是跟setevent最不相同的地方!).

            Collapse
            				  #include <windows.h>
            				  #include <process.h>
            				  #include <stdio.h>
              
              HANDLE hEvent1, hEvent2;
              int a[ 5 ];
              
              void Thread( void* pParams )
              {
                 int i, num = 0;
            
                 while ( TRUE )
                 {
                    WaitForSingleObject( hEvent2, INFINITE );
                    for ( i = 0; i < 5; i++ ) a[ i ] = num;
                    SetEvent( hEvent1 );
                    num++;
                 }
              }
              
              int main( void )
              {
                 hEvent1 = CreateEvent( NULL, FALSE, TRUE, NULL );
                 hEvent2 = CreateEvent( NULL, FALSE, FALSE, NULL );
              
                 _beginthread( Thread, 0, NULL );
              
                 while( TRUE )
                 { 
                    WaitForSingleObject( hEvent1, INFINITE );
                    printf( "%d %d %d %d %d\n", 
                            a[ 0 ], a[ 1 ], a[ 2 ],
                            a[ 3 ], a[ 4 ] );
                    SetEvent( hEvent2 );
                 }
                 return0;
              }
            

            If you are running Windows 9x/NT/2000, you can run this program by clicking here.

            Summary of Synchronization Objects

            The MSDN News for July/August 1998 has a front page article on Synchronization Objects. The following table is from that article:

            Name Relative speed Cross process Resource counting Supported platforms
            Critical Section Fast No No (exclusive access) 9x/NT/CE
            Mutex Slow Yes No (exclusive access) 9x/NT/CE
            Semaphore Slow Yes Automatic 9x/NT
            Event Slow Yes Yes 9x/NT/CE
            Metered Section Fast Yes Automatic 9x/NT/CE

            by?William T. Block


            from codeproject

            謝謝回復(fù)的補充 ~~,上面拼錯了個詞,改過。。譯完了

            posted on 2007-02-16 14:06 Gohan 閱讀(985) 評論(1)  編輯 收藏 引用 所屬分類: C++

            Feedback

            # re: 翻譯一篇文章Introduction to Multi-threaded Code 多線程編程的一些代碼(先翻一點) 2007-02-22 17:10 池鳳彬

            http://www.codeproject.com/script/profile/whos_who.asp?vt=arts&id=244

            William T. Block View details
            Status Gold. Member No. 244

            View Member's Blog.
            Awards
            Messages Posted 11 - Poster
            Articles Submitted
            3 - Contributor
            Biography Bill's recent projects include graphical displays and printing of real-time data for the Oil Industry.

            "I started programming Windows' applications right after the release of Windows 1.0 and I am now actively working with Microsoft .NET"

            He currently works for Baker Hughes in the Houston, Texas area.
            Birthday Thursday 17th November, 1949
            Location United States
            Occupation Software development
            Interests C++, MFC, Win32, C#, ASP.NET
            Member since Thursday 6th July, 2000
            (6 years, 7 months) Gold Level
            Homepage http://www.wtblock.com/resume/  回復(fù)  更多評論   

            精品国产91久久久久久久a| 国内精品欧美久久精品| 成人久久免费网站| 婷婷久久久亚洲欧洲日产国码AV| 久久久久久久波多野结衣高潮| 亚洲人成伊人成综合网久久久| 久久精品中文无码资源站| 国内精品久久久久影院免费| 久久精品无码专区免费青青| 国产精品久久久久一区二区三区| 亚洲第一永久AV网站久久精品男人的天堂AV | 国产精品久久久香蕉| 奇米综合四色77777久久| 99久久精品国产一区二区三区| 99久久免费国产精品特黄| 狠狠色噜噜狠狠狠狠狠色综合久久| 欧美性大战久久久久久| 996久久国产精品线观看| 久久人妻无码中文字幕| 久久国产综合精品五月天| 久久久久99精品成人片试看| 亚洲?V乱码久久精品蜜桃 | 美女久久久久久| 狠狠色丁香久久婷婷综| 亚洲精品tv久久久久久久久| 久久免费大片| 久久精品无码一区二区三区免费 | 久久久久99精品成人片欧美| 伊人情人综合成人久久网小说 | MM131亚洲国产美女久久| 婷婷久久五月天| 亚洲另类欧美综合久久图片区| 久久九九久精品国产| 久久91精品国产91久久户| 久久国产欧美日韩精品| 久久精品人人做人人妻人人玩 | 国产精品久久午夜夜伦鲁鲁| 亚洲va中文字幕无码久久不卡| 久久久精品国产免大香伊| 久久精品人妻中文系列| 久久久久久久精品成人热色戒|