マルチスレッドでfork関数を使用すると、デッドロックとソリューションが発生します.

2764 ワード

マルチスレッドプログラミングでは、あるスレッドがfork()関数を呼び出してサブプロセスを作成すると、作成したサブプロセスは親プロセスのすべてのロックを継承します.
親プロセスにロックがかかっていて、子プロセスでロックが再ロックされている場合は、デッドロックの原因となるコードを次に示します.
#include
#include
#include
#include
#include
pthread_mutex_t mutex;

void *child(void *arg)
{
	printf("child thread add mutex
"); pthread_mutex_lock(&mutex); // 5 , sleep(5); pthread_mutex_unlock(&mutex); } int main() { pthread_mutex_init(&mutex, NULL); pthread_t pid; pthread_create(&pid ,NULL, child, NULL); // 1 sleep(1); pid = fork(); if(pid < 0) { pthread_join(pid, NULL); pthread_mutex_destroy(&mutex); return 1; } else if(pid == 0) { printf("child process, get lock
"); // , pthread_mutex_lock(&mutex); printf("die mutex blocking
"); pthread_mutex_unlock(&mutex); exit(0); } else { wait(NULL); } pthread_join(pid, NULL); pthread_mutex_destroy(&mutex); return 0; }

ソリューション:
pthread_を使用できますatfork()は、スレッド内の反発ロックの状態をクリーンアップします.
関数のプロトタイプ:
    #include
    pthread_atfork(void (*prepare)(void), void(*parent)(void), void(*child)(void))
prepareパラメータ:fork()関数がサブプロセスを作成する前に呼び出され、マルチスレッド内のロックをロック操作するために使用できます.
parentパラメータ:fork()関数がサブプロセスを作成した後、fork()関数が戻る前に親プロセスで実行され、マルチスレッド内のロックをロック解除するために使用できます.
childパラメータ:fork()関数が戻る前にサブプロセスで実行し、マルチスレッド内のロックをロック解除するために使用できます.
修正後のコード
#include
#include
#include
#include
#include
pthread_mutex_t mutex;

void prepare()
{
	pthread_mutex_lock(&mutex);
}

void parent()
{
	pthread_mutex_unlock(&mutex);
}

void child()
{
	pthread_mutex_unlock(&mutex);
}
void *child(void *arg)
{
	printf("child thread add mutex
"); pthread_mutex_lock(&mutex); // 5 , sleep(5); pthread_mutex_unlock(&mutex); } int main() { pthread_mutex_init(&mutex, NULL); pthread_t pid; pthread_create(&pid ,NULL, child, NULL); // 1 sleep(1); // pthread_atfork() , pthread_atfork(prepare, parent, child); pid = fork(); if(pid < 0) { pthread_join(pid, NULL); pthread_mutex_destroy(&mutex); return 1; } else if(pid == 0) { printf("child process, get lock
"); // , pthread_mutex_lock(&mutex); printf("die mutex blocking
"); pthread_mutex_unlock(&mutex); exit(0); } else { wait(NULL); } pthread_join(pid, NULL); pthread_mutex_destroy(&mutex); return 0; }