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
したがって、私がやろうとしているのは、キューから順番に読み取り/削除するだけです。
問題は、再帰ミューテックスを宣言する方法に関する例がないことです。または、いくつかありますが、私にはコンパイルされません。
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
再帰的なミューテックスを作成するには、次を使用します。
#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);
Linuxでは(ただし、これは他のシステムに移植できません)、mutexがグローバル変数または静的変数である場合、次のように初期化できます。
_static pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
_
(ところで、例はpthread_mutex_init(3)
man pages!からです!)
ミューテックスを作成するときに、ミューテックス属性を追加する必要があります。
pthread_mutexattr_init
を呼び出し、次にpthread_mutexattr_settype
でPTHREAD_MUTEX_RECURSIVE
を呼び出し、pthread_mutex_init
でこれらの属性を使用します。詳細については、man pthread_mutexattr_init
をお読みください。