web-dev-qa-db-ja.com

C:POSIXスレッドで再帰的ミューテックスをどのように宣言しますか?

Pthreadを使用して再帰的なmutexを宣言する方法について少し混乱しています。私がやろうとしていることは、一度に1つのスレッドのみがコードの一部(関数を含む)を実行できるようにすることですが、懐疑論の後、ミューテックスの使用はうまくいかないことがわかり、代わりに再帰的なミューテックスを使用する必要があります。ここに私のコードがあります:

pthread_mutex_lock(&mutex);                   // LOCK

item = queue_peek(queue);                     // get last item in queue
item_buff=item;                               // save item to a buffer
queue_removelast(queue);                      // remove last item from queue

pthread_mutex_unlock(&mutex);                 // UNLOCK

したがって、私がやろうとしているのは、キューから順番に読み取り/削除するだけです。

問題は、再帰ミューテックスを宣言する方法に関する例がないことです。または、いくつかありますが、私にはコンパイルされません。

45
Pithikos

Michael Foukarakisのコードはほとんど問題ありませんが、mutexを2回初期化し、未定義の動作を引き起こします。それだけである必要があります:

pthread_mutex_t Mutex;
pthread_mutexattr_t Attr;

pthread_mutexattr_init(&Attr);
pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&Mutex, &Attr);

私は実際にこのコードを実稼働環境で使用していますが、Linux、Solaris、HP-UX、AIX、Mac OSX、FreeBSDで正しく動作することを知っています。

これをコンパイルするには、適切なリンカーフラグを追加する必要もあります。

AIX, Linux, FreeBSD:
CPLATFORM += -pthread

mingw32:
LDFLAGS += -lpthread
80
Piotr Kukielka

再帰的なミューテックスを作成するには、次を使用します。

#include <pthread.h>
int pthread_mutexatttr_settype(pthread_mutexattr_t *attr,
                               int type);

タイプはPTHREAD_MUTEX_RECURSIVE

戻り値を確認することを忘れないでください!

例:

/* or PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP */
pthread_mutex_t       mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_t   mta;

または、実行時に初期化する(両方ともしないでください、未定義の動作です):

pthread_mutexattr_init(&mta);
/* or PTHREAD_MUTEX_RECURSIVE_NP */
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);

pthread_mutex_init(&mutex, &mta);
16

Linuxでは(ただし、これは他のシステムに移植できません)、mutexがグローバル変数または静的変数である場合、次のように初期化できます。

_static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
_

(ところで、例はpthread_mutex_init(3)man pages!からです!)

14

ミューテックスを作成するときに、ミューテックス属性を追加する必要があります。

pthread_mutexattr_initを呼び出し、次にpthread_mutexattr_settypePTHREAD_MUTEX_RECURSIVEを呼び出し、pthread_mutex_initでこれらの属性を使用します。詳細については、man pthread_mutexattr_initをお読みください。

2
hamstergene