5.8fork父子进程
-
實驗4-2:fork父子進程
- 實驗?zāi)康?#xff1a;
理解fork創(chuàng)建子進程的本質(zhì)
?
- 實驗要求:
1、按如下要求編寫程序:
(1)、打開一個有內(nèi)容的文件;
(2)、調(diào)用fork創(chuàng)建子進程;
(3)、讀文件的第一個字符輸出打印出來;
(4)、看看父進程和子進程分別讀到的字符是什么
2、按如下要求編寫程序:
(1)、調(diào)用fork創(chuàng)建子進程;
(2)、打開一個有內(nèi)容的文件;
(3)、讀文件的第一個字符輸出打印出來;
(4)、看看父進程和子進程分別讀到的字符是什么
3、比較1和2的區(qū)別
?
- 實驗步驟:
- 父進程: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、實驗結(jié)論
fork創(chuàng)建進程之后再打開文件,文件在主進程和子進程分別執(zhí)行打開
打開文件的文件記錄表分別被父子進程創(chuàng)建,對應(yīng)有2個讀寫位置
所以2個進程都讀到第一個字符a
?
- 實驗總結(jié):
1、多個進程對同一文件讀操作不會相互干擾
2、這是建立在各個進程都執(zhí)行open文件前提下的
3、每open一次,系統(tǒng)會在該進程的用戶空間創(chuàng)建一個文件記錄表,記錄了打開文件的狀態(tài)信息(包括文件讀寫偏移位置)
?
實驗心得:
????Linux是出了名的多線程的操作實驗,該實驗實現(xiàn)一個父進程和一個子進程,兩者實現(xiàn)信息的交流。上面是我的實現(xiàn)過程。謝謝。
?
轉(zhuǎn)載于:https://www.cnblogs.com/FORFISH/p/4201826.html
總結(jié)
以上是生活随笔為你收集整理的5.8fork父子进程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 消费明星隐私是不是一种病态?
- 下一篇: C++ primer第五版随笔--201