青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++樂(lè)園

C/C++ 交流

  C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  12 隨筆 :: 18 文章 :: 14 評(píng)論 :: 0 Trackbacks

將 Win32 C/C++ 應(yīng)用程序遷移到 POWER 上的 Linux,第 3 部分: 信號(hào)

developerWorks
文檔選項(xiàng)
將打印機(jī)的版面設(shè)置成橫向打印模式

打印本頁(yè)

將此頁(yè)作為電子郵件發(fā)送

將此頁(yè)作為電子郵件發(fā)送


級(jí)別: 初級(jí)

Nam Keung (mailto:namkeung@us.ibm.com), 高級(jí)程序員, IBM 

2005 年 4 月 21 日

將您的 Win32 C/C++ 應(yīng)用程序遷移到 POWER™ 上的 Linux™,并從信號(hào)(semaphore)應(yīng)用程序接口(application program interface,API)的角度理解 Win32 到 Linux 的映射。Nam Keung 將通過(guò)詳細(xì)的代碼示例來(lái)為您描述這一過(guò)程。

介紹

本系列第三篇文章從信號(hào)的角度闡述了 Win32 C/++ 應(yīng)用程序向 POWER 上的 Linux 的遷移。本系列的第 1 部分介紹了 Win32 API 映射,第 2 部分從互斥(mutex)API 的角度集中闡述了如何將 Win32 映射到 Linux。在繼續(xù)閱讀之前,建議您先去閱讀本系列的第 1 部分和第 2 部分。





回頁(yè)首


信號(hào)

信號(hào)是包含有一個(gè)正數(shù)的資源。信號(hào)允許進(jìn)程通過(guò)一個(gè)單一的原子操作來(lái)測(cè)試和設(shè)置那個(gè)整數(shù)的值,以此實(shí)現(xiàn)同步。通常,信號(hào)的主要用途是同步某個(gè)線程與其他線程的動(dòng)作。在多個(gè)進(jìn)程競(jìng)爭(zhēng)訪問(wèn)同一操作系統(tǒng)資源時(shí),這也是協(xié)調(diào)或者同步那些行為的一種實(shí)用技術(shù)。

Linux 支持 Portable Operating System Interface(POSIX)信號(hào)以及 pthread 條件變量,以此來(lái)映射 Win32 信號(hào) API。它們各有其優(yōu)缺點(diǎn)。您應(yīng)該基于應(yīng)用程序的邏輯來(lái)判斷使用哪種方法。在映射事件信號(hào)的過(guò)程中需要考慮的方面包括:

  • 信號(hào)的類型:Win32 既支持有名稱的事件信號(hào),也支持無(wú)名稱的事件信號(hào)。有名稱的信號(hào)是在多個(gè)進(jìn)程間共享的。Linux 不支持這種方案。本文中列出的一個(gè)進(jìn)程間通信(Inter-Process Communication,IPC)消息隊(duì)列示例代碼將向您展示如何來(lái)解決此問(wèn)題。
  • 初始狀態(tài):在 Win32 中,信號(hào)可能會(huì)有初始值。在 Linux 中,POSIX 信號(hào)支持此功能,但 pthreads 不支持。在使用 pthreads 時(shí)您需要考慮到這一點(diǎn)。
  • 超時(shí):Win32 事件信號(hào)支持定時(shí)等待。在 Linux 中,POSIX 信號(hào)實(shí)現(xiàn)只支持不確定的等待(阻塞)。pthreads 實(shí)現(xiàn)既支持阻塞也支持超時(shí)。pthread_cond_timedwait() 調(diào)用能給出等待期間的超時(shí)的值,pthread_cond_wait() 則用于不確定的等待。
  • 發(fā)信號(hào):在 Win32 中,發(fā)出信號(hào)會(huì)喚醒等待那個(gè)信號(hào)的所有線程。在 Linux 中,POSIX 線程實(shí)現(xiàn)一次只喚醒一個(gè)線程。pthreads 實(shí)現(xiàn)的 pthread_cond_signal() 調(diào)用會(huì)喚醒一個(gè)線程,pthread_cond_broadcast() 調(diào)用會(huì)向所有等待那個(gè)信號(hào)的線程發(fā)出信號(hào)。

 


表 1. 信號(hào)映射表
Win32 pthread Linux POSIX
CreateSemaphore pthread_mutex_init(&(token)->mutex, NULL))
pthread_cond_init(&(token)->condition, NULL))
sem_init
CloseHandle (semHandle) pthread_mutex_destroy(&(token->mutex))
pthread_cond_destroy(&(token->condition))
sem_destroy
ReleaseSemaphore(semHandle, 1, NULL) pthread_cond_signal(&(token->condition)) sem_post
WaitForSingleObject(semHandle,
INFINITE)
WaitForSingleObject(semHandle,
timelimit)
pthread_cond_wait(&(token->condition),
&(token->mutex))
pthread_cond_timedwait(&(token
->condition), &(token->mutex))
sem_wait
sem_trywait




回頁(yè)首


條件變量

條件變量讓開(kāi)發(fā)者能夠?qū)崿F(xiàn)一個(gè)條件,在這個(gè)條件下線程執(zhí)行然后被阻塞。Microsoft® Win32 接口本身不支持條件變量。為解決此缺憾,我使用 POSIX 條件變量模擬同步原語(yǔ),并在一系列文章中對(duì)此進(jìn)行了概述。在 Linux 中,它可以確保因某條件被阻塞的線程,當(dāng)那個(gè)條件改變時(shí),會(huì)被解除阻塞。它還允許您原子地(atomically)解除互斥的鎖定,并等待條件變量,而不會(huì)有干涉其他線程的可能。不過(guò),每個(gè)條件變量都應(yīng)該伴有一個(gè)互斥。前面的表 1 給出了用于線程間同步的 pthread 條件變量。





回頁(yè)首


創(chuàng)建信號(hào)

在 Win32 中,CreateSemaphore 函數(shù)可以創(chuàng)建一個(gè)有名稱的或者無(wú)名稱的信號(hào)對(duì)象。Linux 不支持有名稱的信號(hào)。


清單 1. 創(chuàng)建信號(hào)
HANDLE CreateSemaphore (
                            LPSECURITY_ATTRIBUTES	lpSemaphoreAttributes,
                            LONG			lInitialCount,
                            LONG			lMaximunCount,
                            LPCTSTR			lpName
                            );
                            

在 Linux 中,sem_init() 調(diào)用會(huì)創(chuàng)建一個(gè) POSIX 信號(hào):


清單 2. POSIX 信號(hào)
                            int sem_init(sem_t *sem, int pshared, unsigned int value
                            

Linux 使用 pthread_condition_init 調(diào)用在當(dāng)前進(jìn)程內(nèi)創(chuàng)建信號(hào)對(duì)象,在其中維持一個(gè)在零與最大值之間的計(jì)數(shù)值。每次有某個(gè)線程完成對(duì)信號(hào)的等待,這個(gè)計(jì)數(shù)值會(huì)減小,而每次當(dāng)某個(gè)線程釋放這個(gè)信號(hào)時(shí),計(jì)數(shù)值增加。當(dāng)計(jì)數(shù)值成為零時(shí),信號(hào)對(duì)象的狀態(tài)成為 non-signaled。


清單 3. 創(chuàng)建信號(hào)對(duì)象的 pthread_condition_init 調(diào)用
                            int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
                            


清單 4. Win32 示例代碼
                            HANDLE semHandle;
                            semHandle = CreateSemaphore(NULL, 0, 256000, NULL);
                            /* Default security descriptor     */
                            if( semHandle == (HANDLE) NULL)
                            /* Semaphore object without a name */
                            {
                            return RC_OBJECT_NOT_CREATED;
                            }
                            



清單 5. 相應(yīng)的 Linux 代碼
                            typedef struct
                            {
                            pthread_mutex_t	mutex;
                            pthread_cond_t		condition;
                            int			semCount;
                            }sem_private_struct, *sem_private;
                            sem_private    token;
                            token = (sem_private) malloc(sizeof(sem_private_struct));
                            if(rc = pthread_mutex_init(&(token->mutex), NULL))
                            {
                            free(token);
                            return RC_OBJECT_NOT_CREATED;
                            }
                            if(rc = pthread_cond_init(&(token->condition), NULL))
                            {
                            pthread_mutex_destroy( &(token->mutex) );
                            free(token);
                            return RC_OBJECT_NOT_CREATED;
                            }
                            token->semCount = 0;
                            





回頁(yè)首


銷毀事件信號(hào)

Win32 使用 CloseHandle 來(lái)刪除由 CreateSemaphore 所創(chuàng)建的信號(hào)對(duì)象。


清單 6. 銷毀事件信號(hào)
BOOL CloseHandle (HANDLE hObject);
                            

Linux POSIX 信號(hào)使用 sem_destroy() 來(lái)銷毀無(wú)名稱的信號(hào)。


清單 7. sem_destroy()
                            int sem_destroy(sem_t *sem);

在 Linux pthreads 中,使用 pthread_cond_destroy() 來(lái)銷毀條件變量。


清單 8. pthread_cond_destroy()
                            int pthread_cond_destroy(pthread_cond_t *cond);


清單 9. Win32 代碼和相應(yīng)的 Linux 代碼
Win32 代碼 相應(yīng)的 Linux 代碼
CloseHandle(semHandle); pthread_mutex_destroy(&(token->mutex));

pthread_cond_destroy(&(token->condition));

free (token);




回頁(yè)首


發(fā)布事件信號(hào)

在 Win32 中,ReleaseSemaphore 函數(shù)會(huì)令指定的信號(hào)對(duì)象的計(jì)數(shù)值增加指定數(shù)量。


清單 10. ReleaseSemaphore 函數(shù)
                                BOOL ReleaseSemaphore(
                                HANDLE hSemaphore,
                                LONG 	lReleaseCount,
                                LPLONG	lpPreviousCount
                                );
                                

Linux POSIX 信號(hào)使用 sem_post() 來(lái)發(fā)布事件信號(hào)。這將喚醒阻塞于此信號(hào)的所有線程。


清單 11. sem_post()
                                int sem_post(sem_t * sem);
                                

在 Linux 中,pthread_cond_signal 會(huì)喚醒等待某個(gè)條件變更的某個(gè)線程。Linux 調(diào)用這個(gè)函數(shù)來(lái)為此對(duì)象所標(biāo)識(shí)的信號(hào)發(fā)布一個(gè)事件完成信號(hào)。調(diào)用的線程增加那個(gè)信號(hào)的值。如果信號(hào)的值從零開(kāi)始增加,而且 pthread_cond 中有任何線程被阻塞,那么請(qǐng)等待這個(gè)信號(hào),因?yàn)槠渲幸粋€(gè)會(huì)被喚醒。默認(rèn)情況下,實(shí)現(xiàn)可以選擇任意的正在等待的線程。


清單 12. pthread_cond_signal
                                int pthread_cond_signal(pthread_cond_t *cond);
                                


清單 13. Win32 代碼和相應(yīng)的 Linux 代碼
Win32 代碼 相應(yīng)的 Linux 代碼
ReleaseSemaphore(semHandle, 1, NULL) if (rc = pthread_mutex_lock(&(token->mutex)))
return RC_SEM_POST_ERROR;

token->semCount ++;

if (rc = pthread_mutex_unlock(&(token->mutex)))
return RC_SEM_POST_ERROR;

if (rc = pthread_cond_signal(&(token->condition)))
return RC_SEM_POST_ERROR;




回頁(yè)首


等待事件信號(hào)

Win32 調(diào)用 WaitForSingleObject 函數(shù)來(lái)等待所需要的信號(hào)上事件的完成。當(dāng)?shù)却龁我痪€程同步對(duì)象時(shí),可以使用此方法。當(dāng)對(duì)象被設(shè)置發(fā)出信號(hào)或者超時(shí)時(shí)間段結(jié)束時(shí),這個(gè)方法會(huì)得到通知。如果時(shí)間間隔是 INFINITE,那么它就會(huì)無(wú)止境地等待下去。


清單 14. WaitForSingleObject 函數(shù)
                                    DWORD WaitForSingleObject(
                                    HANDLE hHANDLE,
                                    DWORD	dwMilliseconds
                                    );
                                    

使用 WaitForMultipleObjects 函數(shù)來(lái)等待多個(gè)被通知的對(duì)象。在信號(hào)線程同步對(duì)象中,當(dāng)計(jì)數(shù)器變?yōu)榱銜r(shí),對(duì)象是 non-signaled。


清單 15. WaitForMultipleObjects 函數(shù)
                                    DWORD WaitForMultipleObjects(
                                    DWORD	nCount,
                                    Const	HANDLE* lpHandles,
                                    BOOL	bWaitAll,
                                    DWORD	dwMilliseconds
                                    );
                                    

Linux POSIX 信號(hào)使用 sem_wait() 來(lái)掛起發(fā)出調(diào)用的線程,直到信號(hào)擁有了非零的計(jì)數(shù)值。然后它自動(dòng)地減少信號(hào)的計(jì)數(shù)值。


清單 16. sem_wait() 函數(shù)
                                    int sem_wait(sem_t * sem);
                                    

在 POSIX 信號(hào)中不能使用超時(shí)選項(xiàng)。不過(guò),您可以通過(guò)在某個(gè)循環(huán)中執(zhí)行非阻塞的 sem_trywait() 來(lái)完成此功能,它會(huì)計(jì)算超時(shí)的值。


清單 17. sem_trywait() 函數(shù)
                                    int sem_trywait(sem_t  * sem);
                                    

在 Linux 中,pthread_cond_wait() 會(huì)阻塞發(fā)出調(diào)用的線程。發(fā)出調(diào)用的線程會(huì)減小那個(gè)信號(hào)。如果當(dāng) pthread_cond_wait 被調(diào)用時(shí)信號(hào)是零,則 pthread_cond_wait() 就會(huì)阻塞,直到另一個(gè)線程增加了那個(gè)信號(hào)的值。


清單 18. pthread_cond_wait() 函數(shù)
                                    int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t  *mutex);
                                    

pthread_cond_wait 函數(shù)首先釋放相關(guān)聯(lián)的 external_mutex of type pthread_mutex_t,當(dāng)調(diào)用者檢查條件表達(dá)式時(shí)必須持有它。


清單 19. Win32 代碼和相應(yīng)的 Linux 代碼
Win32 代碼 相應(yīng)的 Linux 代碼
DWORD retVal;

retVal = WaitForSingleObject(semHandle, INFINITE);

if (retVal == WAIT_FAILED) return RC_SEM_WAIT_ERROR
if (rc = pthread_mutex_lock(&(token->mutex)))
return RC_SEM_WAIT_ERROR;

while (token->semCount <= 0)
{
rc = pthread_cond_wait(&(token->condition), &(token->mutex));
if (rc &&errno != EINTR )
break;
}
token->semCount--;

if (rc = pthread_mutex_unlock(&(token->mutex)))
return RC_SEM_WAIT_ERROR;

如果您需要在指定的一段時(shí)間內(nèi)阻塞發(fā)出調(diào)用的線程,那么請(qǐng)使用 pthread_cond_timewait 來(lái)阻塞它。調(diào)用這個(gè)方法來(lái)等待所需要信號(hào)上某個(gè)事件的完成,等待指定的一段時(shí)間。


清單 20. pthread_cond_timewait
                                        int pthread_cond_timewait(
                                        pthread_cond_t		*cond,
                                        pthread_mutex_t		*mutex,
                                        timespec		*tm
                                        );			




清單 21. Win32 代碼和相應(yīng)的 Linux 代碼
Win32 代碼 相應(yīng)的 Linux 代碼
retVal = WaitForSingleObject(SemHandle, timelimit);

if (retVal == WAIT_FAILED)
return RC_SEM_WAIT_ERROR;

if (retVal == WAIT_TIMEOUT)
return RC_TIMEOUT;
int rc;
struct timespec tm;
struct timeb tp;
long sec, millisec;

if (rc = pthread_mutex_lock(&(token->mutex)))
return RC_SEM_WAIT_ERROR;

sec = timelimit / 1000;
millisec = timelimit % 1000;
ftime( &tp );
tp.time += sec;
tp.millitm += millisec;
if( tp.millitm > 999 )
{
tp.millitm -= 1000;
tp.time++;
}
tm.tv_sec = tp.time;
tm.tv_nsec = tp.millitm * 1000000 ;

while (token->semCount <= 0)
{
rc = pthread_cond_timedwait(&(token->condition), &(token->mutex), &tm);
if (rc && (errno != EINTR) )
break;
}
if ( rc )
{
if ( pthread_mutex_unlock(&(token->mutex)) )
return RC_SEM_WAIT_ERROR );

if ( rc == ETIMEDOUT) /* we have a time out */
return RC_TIMEOUT );

return RC_SEM_WAIT_ERROR );

}
token->semCount--;

if (rc = pthread_mutex_unlock(&(token->mutex)))
return RC_SEM_WAIT_ERROR;




回頁(yè)首


POSIX 信號(hào)示例代碼

清單 22 使用 POSIX 信號(hào)來(lái)實(shí)現(xiàn)線程 A 和 B 之間的同步:


清單 22. POSIX 信號(hào)示例代碼
                                            sem_t sem; /* semaphore object */
                                            int irc;   /* return code */
                                            /* Initialize the semaphore - count is set to 1*/
                                            irc = sem_init (sem, 0,1)
                                            ...
                                            /* In Thread A */
                                            /* Wait for event to be posted */
                                            sem_wait (&sem);
                                            /* Unblocks immediately as semaphore initial count was set to 1 */
                                            .......
                                            /* Wait again for event to be posted */
                                            sem_wait (&sem);
                                            /* Blocks till event is posted */
                                            /* In Thread B */
                                            /* Post the semaphore */
                                            ...
                                            irc = sem_post (&sem);
                                            /* Destroy the semaphore */
                                            irc = sem_destroy(&sem);
                                            





回頁(yè)首


進(jìn)程內(nèi)信號(hào)示例代碼


清單 23. Win32 進(jìn)程內(nèi)信號(hào)示例代碼
                                            #include <stdio.h>
                                            #include <stdlib.h>
                                            #include <windows.h>
                                            void thrdproc      (void   *data);  // the thread procedure (function)
                                            to be executed
                                            HANDLE   semHandle;
                                            int
                                            main( int argc, char **argv )
                                            {
                                            HANDLE    *threadId1;
                                            HANDLE    *threadId2;
                                            int        hThrd;
                                            unsigned   stacksize;
                                            int	    arg1;
                                            if( argc < 2 )
                                            arg1 = 7;
                                            else
                                            arg1 = atoi( argv[1] );
                                            printf( "Intra Process Semaphor test.\n" );
                                            printf( "Start.\n" );
                                            semHandle = CreateSemaphore(NULL, 1, 65536, NULL);
                                            if( semHandle == (HANDLE) NULL)
                                            {
                                            printf("CreateSemaphore error: %d\n", GetLastError());
                                            }
                                            printf( "Semaphor created.\n" );
                                            if( stacksize < 8192 )
                                            stacksize = 8192;
                                            else
                                            stacksize = (stacksize/4096+1)*4096;
                                            hThrd = _beginthread( thrdproc, // Definition of a thread entry
                                            NULL,
                                            stacksize,
                                            "Thread 1");
                                            if (hThrd == -1)
                                            return RC_THREAD_NOT_CREATED);
                                            *threadId1 = (HANDLE) hThrd;
                                            hThrd = _beginthread( thrdproc, // Definition of a thread entry
                                            NULL,
                                            stacksize,
                                            “Thread 2");
                                            if (hThrd == -1)
                                            return RC_THREAD_NOT_CREATED);
                                            *threadId2 = (HANDLE) hThrd;
                                            printf( "Main thread sleeps 5 sec.\n" );
                                            sleep(5);
                                            if( ! ReleaseSemaphore(semHandle, 1, NULL) )
                                            printf("ReleaseSemaphore error: %d\n", GetLastError());
                                            printf( "Semaphor released.\n" );
                                            printf( "Main thread sleeps %d sec.\n", arg1 );
                                            sleep (arg1);
                                            if( ! ReleaseSemaphore(semHandle, 1, NULL) )
                                            printf("ReleaseSemaphore error: %d\n", GetLastError());
                                            printf( "Semaphor released.\n" );
                                            printf( "Main thread sleeps %d sec.\n", arg1 );
                                            sleep (arg1);
                                            CloseHandle(semHandle);
                                            printf( "Semaphor deleted.\n" );
                                            printf( "Main thread sleeps 5 sec.\n" );
                                            sleep (5);
                                            printf( "Stop.\n" );
                                            return OK;
                                            }
                                            void
                                            thread_proc( void *pParam )
                                            {
                                            DWORD  retVal;
                                            printf( "\t%s created.\n", pParam );
                                            retVal = WaitForSingleObject(semHandle, INFINITE);
                                            if (retVal == WAIT_FAILED)
                                            return RC_SEM_WAIT_ERROR;
                                            printf( "\tSemaphor blocked by %s. (%lx)\n", pParam, retVal);
                                            printf( "\t%s sleeps for 5 sec.\n", pParam );
                                            sleep(5);
                                            if( ! ReleaseSemaphore(semHandle, 1, NULL) )
                                            printf("ReleaseSemaphore error: %d\n", GetLastError());
                                            printf( "\tSemaphor released by %s.)\n", pParam);
                                            }
                                            




清單 24. 相應(yīng)的 Linux 進(jìn)程內(nèi)信號(hào)示例代碼
                                            #include <stdio.h>
                                            #include <stdlib.h>
                                            #include <sys/types.h>
                                            #include <unistd.h>
                                            #include <pthread.h>
                                            #include <errno.h>
                                            void  thread_proc (void * data);
                                            pthread_mutexattr_t     attr;
                                            pthread_mutex_t         mutex;
                                            typedef struct
                                            {
                                            pthread_mutex_t         mutex;
                                            pthread_cond_t          condition;
                                            int                     semCount;
                                            }sem_private_struct, *sem_private;
                                            sem_private     token;
                                            int main( int argc, char **argv )
                                            {
                                            pthread_t             threadId1;
                                            pthread_t             threadId2;
                                            pthread_attr_t        pthread_attr;
                                            pthread_attr_t        pthread_attr2;
                                            int			arg1;
                                            int                   rc;
                                            if( argc < 2 )
                                            arg1 = 7;
                                            else
                                            arg1 = atoi( argv[1] );
                                            printf( "Intra Process Semaphor test.\n" );
                                            printf( "Start.\n" );
                                            token =(sem_private)  malloc (sizeof (sem_private_struct));
                                            if(rc = pthread_mutex_init( &(token->mutex), NULL))
                                            {
                                            free(token);
                                            return 1;
                                            }
                                            if(rc = pthread_cond_init(&(token->condition), NULL))
                                            {
                                            printf( "pthread_condition ERROR.\n" );
                                            pthread_mutex_destroy( &(token->mutex) );
                                            free(token);
                                            return 1;
                                            }
                                            token->semCount = 0;
                                            printf( "Semaphor created.\n" );
                                            if (rc = pthread_attr_init(&pthread_attr))
                                            {
                                            printf( "pthread_attr_init ERROR.\n" );
                                            exit;
                                            }
                                            if (rc = pthread_attr_setstacksize(&pthread_attr, 120*1024))
                                            {
                                            printf( "pthread_attr_setstacksize ERROR.\n" );
                                            exit;
                                            }
                                            if (rc = pthread_create(&threadId1,
                                            &pthread_attr,
                                            (void*(*)(void*))thread_proc,
                                            "Thread 1" ))
                                            {
                                            printf( "pthread_create ERROR.\n" );
                                            exit;
                                            }
                                            if (rc = pthread_attr_init(&pthread_attr2))
                                            {
                                            printf( "pthread_attr_init2 ERROR.\n" );
                                            exit;
                                            }
                                            if (rc = pthread_attr_setstacksize(&pthread_attr2, 120*1024))
                                            {
                                            printf( "pthread_attr_setstacksize2 ERROR.\n" );
                                            exit;
                                            }
                                            if (rc = pthread_create(&threadId2,
                                            &pthread_attr2,
                                            (void*(*)(void*))thread_proc,
                                            "Thread 2" ))
                                            {
                                            printf( "pthread_CREATE ERROR2.\n" );
                                            exit ;  // EINVAL, ENOMEM
                                            }
                                            printf( "Main thread sleeps 5 sec.\n" );
                                            sleep( 5 );
                                            if (rc =  pthread_mutex_lock(&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_lock ERROR 1.\n" );
                                            return 1;
                                            }
                                            token->semCount ++;
                                            if (rc = pthread_mutex_unlock&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_unlock ERROR 1.\n" );
                                            return 1;
                                            }
                                            if (rc = pthread_cond_signal(&(token->condition)))
                                            {
                                            printf( "pthread_cond_signal ERROR1.\n" );
                                            return 1;
                                            }
                                            printf( "Semaphor released.\n" );
                                            printf( "Main thread sleeps %d sec.\n", arg1 );
                                            sleep( arg1 );
                                            if (rc =  pthread_mutex_lock(&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_lock ERROR.\n" );
                                            return 1;
                                            }
                                            token->semCount ++;
                                            if (rc = pthread_mutex_unlock(&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_lock ERROR.\n" );
                                            return 1;
                                            }
                                            if (rc = pthread_cond_signal(&(token->condition)))
                                            {
                                            printf( "pthread_cond_signal ERROR.\n" );
                                            return 1;
                                            }
                                            printf( "Semaphor released.\n" );
                                            printf( "Main thread sleeps %d sec.\n", arg1 );
                                            sleep( arg1 );
                                            pthread_mutex_destroy(&(token->mutex));
                                            pthread_cond_destroy(&(token->condition));
                                            printf( "Semaphor deleted.\n" );
                                            printf( "Main thread sleeps 5 sec.\n" );
                                            sleep( 5 );
                                            printf( "Stop.\n" );
                                            return 0;
                                            }
                                            void
                                            thread_proc( void *pParam )
                                            {
                                            int	rc;
                                            printf( "\t%s created.\n", pParam );
                                            if (token == (sem_private) NULL)
                                            return ;
                                            if (rc =  pthread_mutex_lock(&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_lock ERROR2.\n" );
                                            return ;
                                            }
                                            while (token->semCount <= 0)
                                            {
                                            rc = pthread_cond_wait(&(token->condition), &(token->mutex));
                                            if (rc && errno != EINTR )
                                            break;
                                            }
                                            if( rc )
                                            {
                                            pthread_mutex_unlock(&(token->mutex));
                                            printf( "pthread_mutex_unlock ERROR3.\n" );
                                            return;
                                            }
                                            token->semCount--;
                                            if (rc = pthread_mutex_unlock(&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_lock ERROR.\n" );
                                            return ;
                                            }
                                            printf( "\tSemaphor blocked by %s. (%lx)\n", pParam, rc );
                                            printf( "\t%s sleeps for 5 sec.\n", pParam );
                                            sleep( 5 );
                                            if (rc =  pthread_mutex_lock(&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_lock ERROR.\n" );
                                            return ;
                                            }
                                            token->semCount ++;
                                            if (rc = pthread_mutex_unlock(&(token->mutex)))
                                            {
                                            printf( "pthread_mutex_unlock ERROR.\n" );
                                            return ;
                                            }
                                            if (rc = pthread_cond_signal(&(token->condition)))
                                            {
                                            printf( "pthread_cond_signal ERROR.\n" );
                                            return ;
                                            }
                                            printf( "\tSemaphor released by %s. (%lx)\n", pParam, rc );
                                            





回頁(yè)首


進(jìn)程間信號(hào)示例代碼


清單 25. Win32 進(jìn)程間信號(hào)示例代碼,進(jìn)程 1
                                            #include <stdio.h>
                                            #include <windows.h>
                                            #define WAIT_FOR_ENTER  printf( "Press ENTER\n" );getchar()
                                            int main()
                                            {
                                            HANDLE		semaphore;
                                            int		nRet;
                                            DWORD          retVal;
                                            SECURITY_ATTRIBUTES		sec_attr;
                                            printf( "Inter Process Semaphore test - Process 1.\n" );
                                            printf( "Start.\n" );
                                            sec_attr.nLength              = sizeof( SECURITY_ATTRIBUTES );
                                            sec_attr.lpSecurityDescriptor = NULL;
                                            sec_attr.bInheritHandle       = TRUE;
                                            semaphore = CreateSemaphore( &sec_attr, 1, 65536, “456789" );
                                            if( semaphore == (HANDLE) NULL )
                                            return RC_OBJECT_NOT_CREATED;
                                            printf( "Semaphore created. (%lx)\n", nRet );
                                            WAIT_FOR_ENTER;
                                            if( ! ReleaseSemaphore(semaphore, 1, NULL) )
                                            return SEM_POST_ERROR;
                                            printf( "Semaphore Posted. \n");
                                            WAIT_FOR_ENTER;
                                            retVal = WaitForSingleObject (semaphore, INFINITE );
                                            if (retVal == WAIT_FAILED)
                                            return SEM_WAIT_ERROR;
                                            printf( "Wait for Semaphore. \n");
                                            WAIT_FOR_ENTER;
                                            CloseHandle (semaphore);
                                            printf( "Semaphore deleted.\n" );
                                            printf( "Stop.\n" );
                                            return 0;
                                            }
                                            

清單 26 給出了作為支持進(jìn)程間共享的有名稱信號(hào)示例的消息 IPC 代碼。


清單 26. 相應(yīng)的 Linux 進(jìn)程間信號(hào)示例代碼,進(jìn)程 1
                                            #include <stdio.h>
                                            #include <sys/types.h>
                                            #include <sys/sem.h>
                                            #include <sys/stat.h>
                                            #include <errno.h>
                                            #include <unistd.h>
                                            #define WAIT_FOR_ENTER  printf( "Press ENTER\n" );getchar()
                                            struct msgbuf {
                                            long mtype;         /* type of message */
                                            char mtext[1];      /* message text */
                                            };
                                            int main()
                                            {
                                            key_t           msgKey;
                                            int             flag;
                                            struct msgbuf   buff;
                                            int             sem;
                                            int             nRet =0;
                                            printf( "Inter Process Semaphore test - Process 1.\n" );
                                            printf( "Start.\n" );
                                            flag = IPC_CREAT|IPC_EXCL;
                                            if( ( msgKey = (key_t) atol( "456789" ) ) <= 0 )
                                            return 1;
                                            flag |= S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
                                            sem  = (int) msgget( msgKey, flag );
                                            if (sem == -1)
                                            if( errno == EEXIST )
                                            {
                                            flag &= ~IPC_EXCL;
                                            sem = (int) msgget( msgKey, flag );
                                            if (msgctl(sem, IPC_RMID, NULL ) != 0)
                                            return 1;
                                            sem = (int) msgget( msgKey, flag );
                                            if (sem == -1)
                                            return 1;
                                            }
                                            else
                                            return 1;
                                            printf( "Semaphore created. \n" );
                                            WAIT_FOR_ENTER;
                                            buff.mtype = 123;
                                            if( msgsnd( sem, &buff, 1, 0 ) < 0 )
                                            return 1;
                                            printf( "Semaphore Posted. \n" );
                                            WAIT_FOR_ENTER;
                                            if( msgrcv( sem, &buff, 1, 0, 0 ) < 0 )
                                            return 1;
                                            printf( "Wait for Semaphore. \n" );
                                            WAIT_FOR_ENTER;
                                            msgctl(sem, 0, IPC_RMID );
                                            printf( "Semaphore deleted.\n" );
                                            printf( "Stop.\n" );
                                            return 0;
                                            }
                                            




清單 27. Win32 進(jìn)程間信號(hào)示例代碼,進(jìn)程 2
                                            #include <stdio.h>
                                            #include <windows.h>
                                            int main()
                                            {
                                            HANDLE	semaphore;
                                            DWORD   retVal;
                                            printf( "Inter Process Semaphore test - Process 2.\n" );
                                            printf( "Start.\n" );
                                            SECURITY_ATTRIBUTES		sec_attr;
                                            sec_attr.nLength              = sizeof( SECURITY_ATTRIBUTES );
                                            sec_attr.lpSecurityDescriptor = NULL;
                                            sec_attr.bInheritHandle       = TRUE;
                                            semaphore = CreateSemaphore( &sec_attr, 0, 65536, “456789" );
                                            if( semaphore == (HANDLE) NULL )
                                            return RC_OBJECT_NOT_CREATED;
                                            printf( "Semaphore opened. (%lx)\n", nRet );
                                            printf( "Try to wait for semaphore.\n" );
                                            while( ( retVal = WaitForSingleObject( semaphore, 250 ) ) == WAIT_TIMEOUT)
                                            printf( "Timeout. \n");
                                            printf( "Semaphore acquired. \n");
                                            printf( "Try to post the semaphore.\n" );
                                            if( ! ReleaseSemaphore(semaphore, 1, NULL) )
                                            return RC_SEM_POST_ERROR;
                                            printf( "Semaphore posted. \n");
                                            CloseHandle(semaphore);
                                            printf( "Semaphore closed. \n");
                                            printf( "Stop.\n" );
                                            return 0;
                                            }
                                            




清單 28. 相應(yīng)的 Linux 進(jìn)程間信號(hào)示例代碼,進(jìn)程 2
                                            #include <stdio.h>
                                            #include <sys/time.h>
                                            #include <sys/types.h>
                                            #include <sys/sem.h>
                                            #include <sys/stat.h>
                                            #include <errno.h>
                                            #include <unistd.h>
                                            #define RC_TIMEOUT = 3
                                            struct msgbuf {
                                            long mtype;         /* type of message */
                                            char mtext[1];      /* message text */
                                            };
                                            int main()
                                            {
                                            key_t           msgKey;
                                            int             flag=0;
                                            struct msgbuf   buff;
                                            int             sem;
                                            int             nRet =0;
                                            printf( "Inter Process Semaphore test - Process 2.\n" );
                                            printf( "Start.\n" );
                                            if( ( msgKey = (key_t) atol( "456789" ) ) <= 0 )
                                            return 1;
                                            flag |= S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
                                            sem = (int) msgget( msgKey, flag );
                                            if (sem == -1)
                                            if( errno == EEXIST )
                                            {
                                            flag &= ~IPC_EXCL;
                                            sem = (int) msgget( msgKey, flag );
                                            if (msgctl(sem, IPC_RMID, NULL ) != 0)
                                            return 1;
                                            sem = (int) msgget( msgKey, flag );
                                            if (sem == -1)
                                            return 1;
                                            }
                                            else
                                            return 1;
                                            printf( "Semaphore opened. (%lx)\n", nRet );
                                            if( nRet != 0 )
                                            return 0;
                                            printf( "Try to wait for semaphore.\n" );
                                            while( ( nRet = sem_shared_wait_timed( sem, 250 ) ) == 3)
                                            printf( "Timeout. (%lx)\n", nRet );
                                            printf( "Semaphore acquired. (%lx)\n", nRet );
                                            printf( "Try to post the semaphore.\n" );
                                            buff.mtype = 123;
                                            if( msgsnd( sem, &buff, 1, 0 ) < 0 )
                                            return 1;
                                            printf( "Semaphore posted. (%lx)\n", nRet );
                                            if( nRet != 0 )
                                            return 0;
                                            printf( "Semaphore closed. (%lx)\n", nRet );
                                            printf( "Stop.\n" );
                                            return 0;
                                            }
                                            int sem_shared_wait_timed( int sem, unsigned long timelimit)
                                            {
                                            struct msgbuf           buff;
                                            struct timeval          timeOut;
                                            int                     msg[1];
                                            int                     nRet=0;
                                            timeOut.tv_sec  = timelimit / 1000;
                                            timeOut.tv_usec = (timelimit % 1000) * 1000;
                                            msg[0] = sem;
                                            nRet = select( 0x1000, (fd_set *)msg, NULL, NULL, &timeOut );
                                            if(nRet == 0)
                                            return 3;
                                            if( msgrcv( sem, &buff, 1, 0, 0 ) < 0 )
                                            return 1;
                                            }
                                            





回頁(yè)首


結(jié)束語(yǔ)

本系列的第三篇文章從信號(hào) API 的角度講述了從 Win32 到 Linux 的映射,并給出了您可以引用的信號(hào)示例代碼。線程化的、同步的系統(tǒng)所提出的挑戰(zhàn)不僅是設(shè)計(jì)與實(shí)現(xiàn),也包括了質(zhì)量保證的所有階段。當(dāng)進(jìn)行從 Win32 到 Linux 的遷移時(shí),可以將這些文章做為參考。一定要去閱讀本系列中以前的文章。

補(bǔ)充聲明

Microsoft、Windows、Windows NT 和 Windows 徽標(biāo)是 Microsoft Corporation 在美國(guó)和/或其他國(guó)家或地區(qū)的商標(biāo)或注冊(cè)商標(biāo)。

Intel、Intel Inside(logos)、MMX 和 Pentium 是 Intel 公司在美國(guó)和/或其他國(guó)家或地區(qū)的商標(biāo)。

UNIX 是 The Open Group 在美國(guó)和其他國(guó)家或地區(qū)的注冊(cè)商標(biāo)。

Linux 是 Linus Torvalds 在美國(guó)和/或其他國(guó)家或地區(qū)的商標(biāo)。



參考資料



關(guān)于作者

 

Nam Keung 是 IBM 的一名高級(jí)程序員,他曾致力于 AIX 通信開(kāi)發(fā)、AIX 多媒體、SOM/DSOM 開(kāi)發(fā)和 Java 性能方面的工作。他目前的工作包括幫助獨(dú)立軟件提供商(Independent Software Vendors,ISV)進(jìn)行應(yīng)用程序設(shè)計(jì)、部署應(yīng)用程序、性能調(diào)優(yōu)和關(guān)于 pSeries 平臺(tái)的教育。您可以通過(guò) namkeung@us.ibm.com 與 Nam 聯(lián)系。

posted on 2009-05-05 16:17 小不懂^_^ 閱讀(378) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Windows編程
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            ●精品国产综合乱码久久久久| 欧美日韩免费在线观看| 国产在线精品自拍| 久久精品99久久香蕉国产色戒| 亚洲专区欧美专区| 国产欧美 在线欧美| 欧美在线观看天堂一区二区三区 | 亚洲精品乱码久久久久久黑人| 欧美日韩中文字幕综合视频| 宅男66日本亚洲欧美视频| 亚洲一区二区三区精品视频| 国产日韩欧美一区二区三区四区| 久久五月天婷婷| 欧美精品日韩综合在线| 中国女人久久久| 亚洲一区亚洲| 亚洲国产91| 亚洲天堂av电影| 一色屋精品亚洲香蕉网站| 亚洲国产经典视频| 欧美色图首页| 欧美freesex8一10精品| 欧美日韩精品不卡| 久久综合亚州| 国产精品久久一区主播| 久久一区二区三区四区| 欧美日韩中文字幕综合视频| 久久综合色天天久久综合图片| 欧美精品国产一区| 久久久成人网| 国产精品国产三级国产| 麻豆精品国产91久久久久久| 欧美视频一区| 亚洲国产你懂的| 国产主播喷水一区二区| 一区二区欧美日韩| 亚洲国产成人91精品 | 欧美与欧洲交xxxx免费观看| 蜜桃av噜噜一区| 久久米奇亚洲| 欧美性大战久久久久| 欧美波霸影院| 国产综合色在线| 一区二区三区成人| 亚洲久久成人| 奶水喷射视频一区| 快she精品国产999| 国产综合亚洲精品一区二| 一区二区高清在线| 一本色道久久综合狠狠躁篇怎么玩| 午夜在线成人av| 欧美在线免费视频| 国产精品久久久久久久久动漫| 亚洲第一天堂无码专区| 亚洲丰满在线| 久久综合久久久久88| 久久精品国产一区二区三区免费看| 欧美日韩一区二区在线观看| 亚洲国产欧美在线| 亚洲激情六月丁香| 男女视频一区二区| 欧美激情第3页| 亚洲国产日韩欧美在线图片| 久久天堂成人| 欧美激情中文不卡| 亚洲人成小说网站色在线| 久久视频国产精品免费视频在线 | 亚洲美女区一区| 欧美国内亚洲| 亚洲激情电影在线| 一本高清dvd不卡在线观看| 欧美激情一区二区| aa成人免费视频| 亚洲欧美日韩区| 亚洲美女精品一区| 亚洲精品黄网在线观看| 欧美激情久久久久久| 亚洲精品久久久久| 在线一区视频| 国产网站欧美日韩免费精品在线观看| 羞羞视频在线观看欧美| 久久躁狠狠躁夜夜爽| 亚洲第一主播视频| 欧美日韩hd| 亚洲欧美精品在线| 老色批av在线精品| 日韩西西人体444www| 欧美日韩一区二区三区四区在线观看| 一区二区三区视频在线| 久久精品免费播放| 亚洲精品久久久久久久久久久久久 | 欧美与欧洲交xxxx免费观看| 激情av一区| 欧美巨乳波霸| 亚洲欧美电影院| 欧美国产日韩精品免费观看| 一区二区三区欧美成人| 国产视频一区在线观看一区免费| 久久久xxx| 夜夜嗨一区二区| 久久亚洲综合网| 亚洲午夜在线观看| 在线成人欧美| 国产精品久久精品日日| 久久久蜜臀国产一区二区| 亚洲狼人综合| 久久只精品国产| 亚洲欧美另类久久久精品2019| 精品成人国产| 国产精品女人久久久久久| 久久综合久久综合九色| 亚洲欧美日韩爽爽影院| 欧美激情片在线观看| 欧美激情亚洲自拍| 欧美在线视频全部完| 夜夜夜久久久| 亚洲激情自拍| 你懂的一区二区| 久久er99精品| 亚洲一区影院| 亚洲精品色婷婷福利天堂| 国产亚洲一区二区三区在线观看 | 国产精品视频男人的天堂| 欧美.日韩.国产.一区.二区| 亚洲欧美在线视频观看| 亚洲精品视频在线观看网站| 欧美xart系列高清| 久久精品男女| 久久精品国产久精国产思思| 日韩一级黄色av| 亚洲国产高清视频| 狠狠色丁香婷婷综合影院| 国产精品揄拍500视频| 欧美日韩美女在线观看| 欧美第一黄色网| 欧美jizzhd精品欧美巨大免费| 欧美自拍丝袜亚洲| 欧美在线|欧美| 欧美在线一级视频| 欧美亚洲专区| 欧美影院在线| 欧美在线视频a| 久久精品国产精品亚洲综合| 欧美一区二区在线免费观看| 亚洲欧美国产视频| 性感少妇一区| 欧美亚洲综合久久| 羞羞视频在线观看欧美| 欧美中在线观看| 久久综合给合久久狠狠狠97色69| 久久久久天天天天| 久久亚洲精品一区二区| 久久婷婷人人澡人人喊人人爽| 久久久免费精品| 久久午夜精品| 亚洲欧美激情四射在线日| 宅男噜噜噜66一区二区66| 一区二区三区波多野结衣在线观看| 99视频精品| 午夜久久一区| 久久亚洲影院| 欧美久久九九| 国产日韩高清一区二区三区在线| 国产人成精品一区二区三| 狠狠色丁香久久综合频道| 亚洲福利久久| 亚洲图片欧洲图片日韩av| 西西裸体人体做爰大胆久久久| 久久精品国产一区二区三区免费看| 久久精品国产精品亚洲综合| 欧美成人亚洲成人日韩成人| 亚洲日本中文字幕免费在线不卡| 在线一区二区三区四区五区| 亚欧成人精品| 欧美久久久久中文字幕| 国产欧美日韩综合一区在线播放| 在线观看视频欧美| 中文在线一区| 免费国产一区二区| 亚洲作爱视频| 老色批av在线精品| 国产精品久久看| 亚洲国产老妈| 欧美一区二区黄色| 亚洲国产成人久久综合一区| 亚洲男女自偷自拍| 欧美激情五月| 在线观看日韩www视频免费| 亚洲在线中文字幕| 亚洲国产精品一区二区三区| 亚洲欧美国产77777| 欧美精品色综合| 国产农村妇女毛片精品久久莱园子| 尤物在线观看一区| 午夜免费久久久久| 亚洲日本va在线观看| 欧美在线视频免费播放| 国产精品高潮久久| 日韩视频免费观看高清在线视频| 久久免费99精品久久久久久|