5.8fork父子进程
-
實驗4-2:fork父子進程
- 實驗目的:
理解fork創建子進程的本質
?
- 實驗要求:
1、按如下要求編寫程序:
(1)、打開一個有內容的文件;
(2)、調用fork創建子進程;
(3)、讀文件的第一個字符輸出打印出來;
(4)、看看父進程和子進程分別讀到的字符是什么
2、按如下要求編寫程序:
(1)、調用fork創建子進程;
(2)、打開一個有內容的文件;
(3)、讀文件的第一個字符輸出打印出來;
(4)、看看父進程和子進程分別讀到的字符是什么
3、比較1和2的區別
?
- 實驗步驟:
- 父進程:parent.c
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
?
static volatile sig_atomic_t sigflag;
static sigset_t newmask, oldmask, zeromask;
/* signal handler for SIGUSR1 and SIGUSR2 */
static void sig_usr(int signo)
{
sigflag = 1;
return;
}
void TELL_WAIT()
{
if(signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("signal SIGUSR1 error\n");
if(signal(SIGUSR2, sig_usr) == SIG_ERR)
printf("signal SIGUSR2 error\n");
?
sigemptyset(&zeromask);
?
sigemptyset(&newmask);
sigaddset(&newmask, SIGUSR1);
sigaddset(&newmask, SIGUSR2);
?
/* block SIGUSR1 and SIGUSR2, and save current signal mask */
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
printf("SIG_BLOCK error\n");
}
void TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we are done */
}
void WAIT_PARENT()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
?
sigflag = 0;
?
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1);
}
void WAIT_CHILD()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
?
sigflag = 0;
?
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void do_task(char *task_str)
{
printf("%s\n", task_str);
}
/* parent goes first program */
int main()
{
pid_t pid;
?
TELL_WAIT();
?
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
WAIT_PARENT();
do_task("child task\n");
}
else {
do_task("parent task\n");
TELL_CHILD(pid);
}
?
return 0;
}
?
- 父進程:parent.c
?
- 子進程child.c:
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
?
static volatile sig_atomic_t sigflag;
static sigset_t newmask, oldmask, zeromask;
/* signal handler for SIGUSR1 and SIGUSR2 */
static void sig_usr(int signo)
{
sigflag = 1;
return;
}
void TELL_WAIT()
{
if(signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("signal SIGUSR1 error\n");
if(signal(SIGUSR2, sig_usr) == SIG_ERR)
printf("signal SIGUSR2 error\n");
?
sigemptyset(&zeromask);
?
sigemptyset(&newmask);
sigaddset(&newmask, SIGUSR1);
sigaddset(&newmask, SIGUSR2);
?
/* block SIGUSR1 and SIGUSR2, and save current signal mask */
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
printf("SIG_BLOCK error\n");
}
void TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we are done */
}
void WAIT_PARENT()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
?
sigflag = 0;
?
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1);
}
void WAIT_CHILD()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
?
sigflag = 0;
?
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void do_task(char *task_str)
{
printf("%s\n", task_str);
}
?
?
/* child goes first program*/
int main()
{
pid_t pid;
?
TELL_WAIT();
?
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
do_task("child task\n");
TELL_PARENT(getppid());
}
else {
WAIT_CHILD();
do_task("parent task\n");
}
?
return 0;
}
- 編譯運行:
4、實驗結論
fork創建進程之后再打開文件,文件在主進程和子進程分別執行打開
打開文件的文件記錄表分別被父子進程創建,對應有2個讀寫位置
所以2個進程都讀到第一個字符a
?
- 實驗總結:
1、多個進程對同一文件讀操作不會相互干擾
2、這是建立在各個進程都執行open文件前提下的
3、每open一次,系統會在該進程的用戶空間創建一個文件記錄表,記錄了打開文件的狀態信息(包括文件讀寫偏移位置)
?
實驗心得:
????Linux是出了名的多線程的操作實驗,該實驗實現一個父進程和一個子進程,兩者實現信息的交流。上面是我的實現過程。謝謝。
?
轉載于:https://www.cnblogs.com/FORFISH/p/4201826.html
總結
以上是生活随笔為你收集整理的5.8fork父子进程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消费明星隐私是不是一种病态?
- 下一篇: 考二手车评估师需要多少钱?