
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")
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)