次のように、pthread_mutex_lock を呼び出してミューテックスを保護する必要があります。
pthread_mutex_lock(&mutex);
これを行うと、このスレッドで呼び出すまで、他の呼び出しpthread_mutex_lock(mutex)
は返されません。pthread_mutex_unlock
そのため、pthread_create を呼び出そうとすると、新しいスレッドを作成でき、そのスレッドは共有リソースを (誤って) 使用できるようになります。pthread_mutex_lock
関数内から呼び出す必要fooAPI
があります。これにより、関数は共有リソースが利用可能になるまで待機します。
したがって、次のようなものになります。
#include <pthread.h>
#include <stdio.h>
int sharedResource = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* fooAPI(void* param)
{
pthread_mutex_lock(&mutex);
printf("Changing the shared resource now.\n");
sharedResource = 42;
pthread_mutex_unlock(&mutex);
return 0;
}
int main()
{
pthread_t thread;
// Really not locking for any reason other than to make the point.
pthread_mutex_lock(&mutex);
pthread_create(&thread, NULL, fooAPI, NULL);
sleep(1);
pthread_mutex_unlock(&mutex);
// Now we need to lock to use the shared resource.
pthread_mutex_lock(&mutex);
printf("%d\n", sharedResource);
pthread_mutex_unlock(&mutex);
}
編集:プロセス間でリソースを使用する場合は、これと同じ基本的なアプローチに従いますが、メモリを他のプロセスにマップする必要があります。以下は、shmem を使用した例です。
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/wait.h>
struct shared {
pthread_mutex_t mutex;
int sharedResource;
};
int main()
{
int fd = shm_open("/foo", O_CREAT | O_TRUNC | O_RDWR, 0600);
ftruncate(fd, sizeof(struct shared));
struct shared *p = (struct shared*)mmap(0, sizeof(struct shared),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
p->sharedResource = 0;
// Make sure it can be shared across processes
pthread_mutexattr_t shared;
pthread_mutexattr_init(&shared);
pthread_mutexattr_setpshared(&shared, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&(p->mutex), &shared);
int i;
for (i = 0; i < 100; i++) {
pthread_mutex_lock(&(p->mutex));
printf("%d\n", p->sharedResource);
pthread_mutex_unlock(&(p->mutex));
sleep(1);
}
munmap(p, sizeof(struct shared*));
shm_unlink("/foo");
}
p->sharedResource を変更するプログラムの作成は、読者の課題として残されています。:-)
ところで、pthreads がプロセス間で動作するようにするには、ミューテックスに PTHREAD_PROCESS_SHARED 属性を設定する必要があることに注意するのを忘れていました。