1. 程式人生 > >[APUE] 第12張習題解答

[APUE] 第12張習題解答

1 在linux系統中執行12-7中的程式,但把結果重定向到檔案中,解釋結果。

下面是12-7的程式碼:

#include <stdio.h>
#include <pthread.h>

pthread_mutex_t lock1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t lock2 = PTHREAD_MUTEX_INITIALIZER;

void prepare()
{
	printf("preparing locks\n");
	pthread_mutex_lock(&lock1);
	pthread_mutex_lock(&lock2);
}

void parent()
{
	printf("parent unlocking locks\n");
	pthread_mutex_unlock(&lock1);
	pthread_mutex_unlock(&lock2);
}

void child()
{
	printf("child unlocking locks\n");
	pthread_mutex_unlock(&lock1);
	pthread_mutex_unlock(&lock2);
}

void *thr_fn(void *arg)
{
	printf("thread started\n");
	pause();
	return 0;
}

int main(int argc, char const *argv[])
{
	int err;
	pid_t pid;
	pthread_t tid;

	if((err = pthread_atfork(prepare, parent, child)) != 0) {
		printf("can't install fork handlers\n");
	}
	if((err = pthread_create(&tid, NULL, thr_fn, 0)) != 0) {
		printf("can't create thread\n");
	}
	sleep(2);
	printf("parent about to fork\n");
	if((pid = fork()) < 0) {
		printf("fork failed\n");
	}
	else if(pid == 0) {
		printf("child returned from fork\n");
	}
	else {
		printf("parent returned from fork\n");
	}

	return 0;
}

執行時將結果重定向到檔案,結果是:
thread started
parent about to fork
preparing locks
parent unlocking locks
parent returned from fork
thread started
parent about to fork
preparing locks
child unlocking locks
child returned from fork

部分結果出現了兩次,這是因為緩衝區的緣故。如果輸出到終端,由於終端是行緩衝的,因此,輸出一行就會直接輸出到終端,但是,檔案是全緩衝的,因此,只有當緩衝區滿或者程序結束時,緩衝區中的內容才會輸出到檔案中。在fork()之前,建立了執行緒,由於執行緒共享緩衝區,執行緒的printf也會輸出到當前程序的緩衝區,因此,在fork()之前,緩衝區中的內容有:
thread started
parent about to fork

然後,呼叫fork(),首先會呼叫prepare(),由於還是在父程序中,因此,緩衝區中的內容變成了:
thread started
parent about to fork
preparing locks

接著建立子程序,然後,會呼叫parent(),由於parent()會修改父程序的東西,因此,在呼叫parent()之前,會進行寫時拷貝,拷貝緩衝區到子程序中,那麼,此時父子程序緩衝區都是:
thread started
parent about to fork
preparing locks

然後,在父程序地址空間中呼叫parent(),返回到父程序,在子程序地址空間中呼叫child(),返回到子程序,父子程序分別執行之後緩衝區分別是:
//父程序的緩衝區中的內容
thread started
parent about to fork
preparing locks
parent unlocking locks
parent returned from fork

//子程序的緩衝區中的內容
thread started
parent about to fork
preparing locks
child unlocking locks
child returned from fork

等兩個程序結束後就會輸出到檔案了,結果如開始所示。

從這個結果也可以看出,fork()產生一個程序後,確實返回兩次,先返回到父程序,再返回到子程序。

其它題目現在看不太懂,待補充。。。