linux中让子进程执行和父进程不同功能的两种常用方法

linux中让子进程执行和父进程不同功能的两种常用方法,第1张

运维

Linux系统进程控制

行者111111111111111

原创

关注

0点赞·3人阅读

1、进程创建

shell命令行启动程序指令皆是创建了进程,我们通常通过调用fork()函数创建子进程。

1.1、fork()函数用法简介

调用fork后, *** 作系统内核将:

分配新的内存块和内核数据结构给子进程

将父进程部分数据结构内容拷贝至子进程

添加子进程到系统进程列表当中

fork返回,开始调度器调度

1.2、fork函数返回值

子进程返回0,父进程返回的是子进程的pid

原因:fork之后进入内核,申请内存构建子进程PCB、虚拟内存、页表,将子进程设置R状态,放入调度队列,由于创建子进程之后父子进程共享代码,所以父子进程都会有return返回值。返回值返回给变量本质发生了写时拷贝,改变了子进程对应页表的指向,数据映射到了其他区域

1.3、写时拷贝

由于进程要独立,代码不可修改,数据可改,所以默认数据各有一份,但是内存是有限度的,如果把父进程数据全部再拷贝一份,那么太浪费内存,甚至导致fork失败。通常通过写时拷贝实现,就是当父或子进程修改数据时,将要修改的数据拷贝一份,让子进程页表指向新的重复数据在发生修改

代码没有问题,主要是while直接printf,时间太短,打屏输出速度跟不上,你看不到父进程输出,下面我修改了一下,增加了sleep,可以看到效果。

#include<stdio.h>

#include<unistd.h>

#include<sys/wait.h>

using namespace std

int main(int argc, char *argv[])

{

    int pid

    pid = fork()

    if(pid == 0)

    {//子进程

        while(1)

        {

            printf("child\n")

            sleep(1)

        }

    }

    else

    {//父进程

        while(1)

        {

            printf("parent\n")

            sleep(1)

        }

    }

    return 0

}输出结果:

parent

child

parent

child

parent

child

希望能帮助到你,你的好评是我前进的动力!谢谢!

/*

* 使用信号实现父子进程之间的同步

*

* TELL_WAIT(): set things up for TELL_xxx &WAIT_xxx

* TELL_PARENT(): tell parent we are done

* WAIT_PARENT(): wait for parent

* TELL_CHILD(): tell child we are done

* WAIT_CHILD(): wait for child

*

* SIGUSR1: the signal parent sends to child

* SIGUSR2: the signal child sends to parent

*/

#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

}

/* 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

}

/*

* 使用管道实现父子进程同步

*

* 父进程在调用TELL_CHILD 时经由上一个管道写一个字符p,子进程在

* 调用TELL_PARENT时,经由下一个管道写一个字符c。相应的WAIT_XXX

* 函数调用read读一个字符,没有读到字符时阻塞(睡眠等待)。

*

*/

static int pfd1[2], pfd[2]

void TELL_WAIT()

{

if(pipe(pfd1) <0 || pipe(pfd2) <0)

printf("pipe error\n")

}

void TELL_PARENT(pid_t pid)

{

if(write(pfd2[1], "c", 1) != 1)

printf("write error\n")

}

void WAIT_PARENT()

{

char c

if(read(pfd1[0], &c, 1) != 1)

printf("read error\n")

if(c != 'p')

printf("WAIT_PARENT: incorrect data\n")

}

void TELL_CHILD(pid_t pid)

{

if(write(pfd1[1], "p", 1) != 1)

printf("write error\n")

}

void WAIT_CHILD()

{

char c

if(read(pfd1[0], &c, 1) != 1)

printf("read error\n")

if(c != 'c')

printf("WAIT_CHILD: incorrect data\n")

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/8133129.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-13
下一篇2023-04-13

发表评论

登录后才能评论

评论列表(0条)

    保存