栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux 僵死进程 文件操作

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux 僵死进程 文件操作

目录
  • 复制进程:fork()
    • 习题一:
    • 习题二
    • 习题三
    • 习题四
  • 僵死进程
    • test.c
    • 解决方法wait
      • 法一
      • 法二
  • 文件描述符
    • 文件操作
    • open
    • read
    • write
    • close
    • open.c
    • 写一个复制图片

复制进程:fork()

写时拷贝:提高了fork复制的效率

习题一:
int main()
{
    for(int i=0;i<2;i++)
    {
        fork();
        printf("An");

    }
}

打印6个A

父进程 i=0 fork A; i=1 fork A;

右子进程(i=0 此时从fork后开始执行)A; i=1 fork A

左下子进程(i=1)A;

右下子进程(i=1)A;

习题二
int main()
{
    for(int i=0;i<2;i++)
    {
        fork();
        printf("A");

    }
}

打印8个A,原本父进程打了一个A,复制的时候,缓存区也会存着A给子进程

父进程 i=0 fork A(缓冲区); i=1 fork A;

右子进程(i=0 此时从fork后开始执行)A(存在缓冲区); i=1 fork A

左下子进程(i=1)父缓冲区A+A;

右下子进程(i=1)右子缓冲区A+A;

习题三
int main()
{
     fork()||fork();
     printf("An");
}

打印3个A

C语言中||:他会先算前一部分,如果前一部分为真,他将停止运算,如果为假,他才会算第二部分,你这里第一部分就为真了,第二部分当然也就不会算了。

父进程 fork()||fork(); 只执行第一个fork(fork>0),执行后杀死,打印了一个A

子进程 fork()||fork(); 被杀死的第一个fork(==0),因此执行第二个fork(复制出一个子进程),打印一个A

子进程的子进程 fork()||fork(); 被杀死的第一个fork(==0),被杀死第二个fork(==0),打印一个A

习题四
int main()
{
     fork()&&fork();
     printf("An");
}

打印三个A

C语言中:&&且操作 ,&&为界将表达式分为两部分,他会先算前一部分,如果前一部分为假,他将停止运算,如果为真,他才会算第二部分,你这里第一部分就为假了,第二部分当然也就不会算了。

父进程 fork()&&fork(); 执行第一个fork(fork>0),生成子进程1,执行第二个fork,生成子进程2,打印一个A

子进程1 fork()&&fork(); 被杀死的第一个fork(fork==0),不执行第二个fork,打印了一个A

子进程2 fork()&&fork(); 被杀死的第一个fork(fork>0),被杀死的第二个fork(fork==0),打印一个A

僵死进程

僵死(僵尸)进程:子进程先结束,父进程没有调用wait获取子进程的退出码,子进程就变成了僵死进程

(PCB没有被删掉)

test.c
#include
#include
#include
#include
#include

int main()
{
    int n=0;
    char*s=NULL;
    
    pid_t pid=fork();
    assert(pid!=-1);

    if(pid==0)
    {
        n=3;
        s="child";
    }
    else
    {
        n=10;
        s="parent";
    }

    for(int i=0;i 

后台运行,ps查看->可显示僵死进程

stu@stu-virtual-machine:~/Linux/day08$ ./test&
[1] 3669
stu@stu-virtual-machine:~/Linux/day08$ s=parent
s=child
s=child
s=parent
ps
    PID TTY          TIME CMD
   2550 pts/0    00:00:00 bash
   3669 pts/0    00:00:00 test
   3670 pts/0    00:00:00 test
   3671 pts/0    00:00:00 ps
stu@stu-virtual-machine:~/Linux/day08$ s=child
s=parent
s=parent
s=parent
ps
    PID TTY          TIME CMD
   2550 pts/0    00:00:00 bash
   3669 pts/0    00:00:00 test
   3670 pts/0    00:00:00 test 
   3672 pts/0    00:00:00 ps
stu@stu-virtual-machine:~/Linux/day08$ s=parent
s=parent
s=parent
s=parent
s=parent
解决方法wait 法一

获得退出码(man 3 wait)

#include
pid_t wait(int *stat loc)

test.c

#include
#include
#include
#include
#include
#include

int main()
{
    int n=0;
    char*s=NULL;
    
    pid_t pid=fork();
    assert(pid!=-1);

    if(pid==0)
    {
        n=3;
        s="child";
    }
    else
    {
        n=10;
        s="parent";
        int val=0;
        wait(&val);
        printf("exit_code=%dn",val);
    }

    for(int i=0;i 

结果

stu@stu-virtual-machine:~/Linux/day08$ ./test
s=child
s=child
s=child
exit_code=768    
s=parent
s=parent
s=parent
s=parent
s=parent
s=parent
s=parent
s=parent
s=parent
s=parent

768>>8 = 3

法二

判断程序正常结束 获得退出码

test.c

#include
#include
#include
#include
#include
#include

int main()
{
    int n=0;
    char*s=NULL;
    
    pid_t pid=fork();
    assert(pid!=-1);

    if(pid==0)
    {
        n=3;
        s="child";
    }
    else
    {
        n=10;
        s="parent";
        int val=0;
        wait(&val);
        if(WIFEXITED(val))//判断程序正常结束
        {
            printf("exit_code=%dn",WEXITSTATUS(val));//提取退出码
        }
    }

    for(int i=0;i 

结果

stu@stu-virtual-machine:~/Linux/day08$ ./tests=childs=childs=childexit_code=3s=parents=parents=parents=parents=parents=parents=parents=parents=parents=parent

父进程先于子进程结束不是僵死进程

因为子进程在父进程结束后被init接收,init pid=1

test.c

#include
#include
#include
#include
#include
#include

int main()
{
    int n=0;
    char*s=NULL;
    
    pid_t pid=fork();
    assert(pid!=-1);

    if(pid==0)
    {
        n=7;
        s="child";
    }
    else
    {
        n=3;
        s="parent";
        
    }

    for(int i=0;i 

结果(以前init接管,ppid=1,现在不一定)

stu@stu-virtual-machine:~/Linux/day08$ ./tests=parent,pid=3849,ppid=2550s=child,pid=3850,ppid=3849s=parent,pid=3849,ppid=2550s=child,pid=3850,ppid=3849s=child,pid=3850,ppid=3849s=parent,pid=3849,ppid=2550s=child,pid=3850,ppid=3849stu@stu-virtual-machine:~/Linux/day08$ s=child,pid=3850,ppid=1816s=child,pid=3850,ppid=1816s=child,pid=3850,ppid=1816
文件描述符 文件操作

Linux open read write close 系统调用(在内核中实现)

C语言 fopen fread fwrite fclose 库函数(/usr/lib/c.so 在库中实现)

Windows 分 文本文件 和 二进制文件,Linux不区分

man 2 openman 2 readman 2 writeman 2 close
open
int open(const char* pathname, int flags);//用于打开一个已存在的文件int open(const char* pathname, int flags,mode_t mode);//用于新建一个文件,并设置访问权限

pathname:将要打开的文件路径和名称

flags : 打开标志,如 O_WRonLY 只写打开

O_RDonLY 只读打开

O_RDWR 读写方式打开

O_CREAT 文件不存在则创建

O_APPEND 文件末尾追加

O_TRUNC 清空文件,重新写入

mode: 权限 如:“0600”----读写4+2

返回值:为文件描述符

read
ssize_t read(int fd, void* buf, size_t count);

fd 对应打开的文件描述符

buf 存放数据的空间

count 计划一次从文件中读多少字节数据

返回值:为实际读到的字节数

write
ssize_t write(int fd, const void* buf,size_t count);

fd 对应打开的文件描述符

buf 存放待写入的数据

count 计划一次向文件中写多少数据

close
int close(int fd);

fd 要关闭的文件描述符

open.c

#include#include#include#include#include#include#includeint main(){    int fd=open("file.txt",O_WRONLY|O_CREAT,0600);    assert(fd!=-1);    write(fd,"hello",5);    close(fd);}

结果

stu@stu-virtual-machine:~/Linux/day08$ ./openstu@stu-virtual-machine:~/Linux/day08$ lsfile.txt  main  main.c  open  open.c  test  test.cstu@stu-virtual-machine:~/Linux/day08$ cat file.txthello stu@stu-virtual-machine:~/Linux/day08$ 

#include
#include
#include
#include
#include
#include
#include

int main()
{
    int fd=open("file.txt",O_RDONLY);
    assert(fd!=-1);

    char buff[128]={0};
    int n=read(fd,buff,127);//n==0,表示读到了文件末尾
    //只读127防止溢出
    printf("buff=%sn",buff);

    close(fd);
}

结果

stu@stu-virtual-machine:~/Linux/day08$ ./open
buff=hello
写一个复制图片

open.c

#include
#include
#include
#include
#include
#include
#include

int main()
{
    int fdr=open("1.jpg",O_RDONLY);
    int fdw=open("5.jpg",O_WRONLY|O_CREAT,0600);
    if(fdr==-1||fdw==-1)
    {
        return 0;
    }

    char buff[1024]={0};
    int n=0;
    while((n=read(fdr,buff,1024))>0)
    {
        write(fdw,buff,n);
    }

    close(fdr);
    close(fdw);
}

结果

stu@stu-virtual-machine:~/Linux/day08$ ./open
stu@stu-virtual-machine:~/Linux/day08$ ls 
5.jpg     main    open    test
file.txt  main.c  open.c  test.c
stu@stu-virtual-machine:~/Linux/day08$ ls -l
总用量 76
-rw------- 1 stu stu     0 11月 30 17:53 5.jpg
-rw------- 1 stu stu     5 11月 30 17:34 file.txt
-rwxrwxr-x 1 stu stu 16736 11月 30 15:29 main
-rw-rw-r-- 1 stu stu   322 11月 30 15:29 main.c
-rwxrwxr-x 1 stu stu 16872 11月 30 17:52 open
-rw-rw-r-- 1 stu stu   743 11月 30 17:52 open.c
-rwxrwxr-x 1 stu stu 17016 11月 30 16:43 test
-rw-rw-r-- 1 stu stu   664 11月 30 16:43 test.c
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/675989.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号