0

私が Web で見ている例のほとんどでは、pthread_mutex_t がグローバル空間のファイルの先頭にあり、Linux ミューテックスはグローバルでなければならないということをどこかで読んだと思います。これは本当ですか?

編集: Linux に移植している Win32 マルチスレッド コードがいくつかあります。Windows コードには、ミューテックスの作成やロック/ロック解除などをカプセル化するラッパー関数がいくつかあります。私の理解ではCreate()、Windows の API 呼び出しの 1 つによって作成されたすべての同期プリミティブは、インスタンス フィールドに格納して後で使用できる HANDLE を返します。この場合、WaitForSingleObject() のラッパーである Lock() 関数で使用されます。Linux の場合、ミューテックスをインスタンス フィールドに格納pthread_mutex_lock()/pthread_cond_wait()し、Lock() 関数を呼び出すだけで、Windows と同じ動作を期待できますか?

Nv_Mutex::Nv_Mutex(Nv_XprocessID name)
{

#if defined(WIN32)
    if((handle = ::CreateMutexA(0, false, name)) == NULL)
    {
        throw Nv_EXCEPTION(XCPT_ResourceAllocationFailure, GetLastError());
    }

    isCreator = !(::GetLastError() == ERROR_ALREADY_EXISTS);
#else
    if (name == Nv_XprocessID_NULL) {
        /*
        pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;                     // Fast
        pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;     // Recursive
        pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; // Errorcheck
        */
        mutex = PTHREAD_MUTEX_INITIALIZER;
        // attributes??

        if (pthread_mutex_init(&mutex, NULL) != 0) {
            throw Nv_EXCEPTION(XCPT_ResourceAllocationFailure, GetLastError());
        }
    }
    else {
        // insert code for named mutex (needed for shared mutex across processes) here.
    }

    //isCreator = !(GetLastError() == EBUSY);
#endif
}

bool                
Nv_Mutex::Lock(const char *f, int l, Nv_uint32 timeout)
{

    switch(WaitForSingleObject(handle, timeout))
    {
        case WAIT_OBJECT_0:
            file = f;
            line = l;
            return true;

        case WAIT_TIMEOUT:
            return false;
    }

    throw Nv_EXCEPTION(XCPT_WaitFailed, GetLastError());
}
4

2 に答える 2

1

要件が少し間違っています。ミューテックスはグローバルである必要はありませんが、非静的ミューテックスを静的に初期化することはできません。ただし、mutex を呼び出す前に静的に初期化する必要はありませんpthread_mutex_init。したがって、静的イニシャライザを使用せず、代わりに を呼び出してpthread_mutex_initください。

実際には動作しますが、これは実装の詳細による運によるものです。実装の詳細に依存しないでください。

静的初期化は、静的に ALLOCATED storage[.] に対してのみ有効です ... C 構文では、「自動」変数で静的初期化マクロを使用できますが、これは POSIX 標準によって明確に禁止されています。それは正しくなく、移植性がありません。-デビッド・ブテンホフ

于 2012-12-06T19:18:54.930 に答える
1

いいえ、範囲指定できます。実際のミューテックス ポインターについて特別なことは何もありません。

于 2012-12-06T04:30:52.853 に答える