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

Linux进程复制与替换

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

Linux进程复制与替换

Linux 进程复制与替换
    • 1. 主函数参数介绍
    • 2. printf函数输出问题
    • 3. 复制进程fork
      • (1)fork方法
      • (2)fork练习
    • 4. 僵死进程及处理方法
    • 5. 操作文件的系统调用
      • (1)文件的读写
      • (2)完成对普通文件的复制
    • 6. 系统调用和库函数的区别
    • 7. 进程替换

1. 主函数参数介绍

int main( int argc, char* argv[], char* envp[])
(1) argc 参数个数
(2) argv 参数内容
(3) envp 环境变量


代码执行结果

2. printf函数输出问题

printf 函数并不会直接将数据输出到屏幕,而是先放到缓冲区中,只有以下三种情况满足,才会输出到屏幕。
1) 缓冲区满
2) 强制刷新缓冲区 fflush
3) 程序结束时

3. 复制进程fork (1)fork方法


#include
#include
#include
#include
#include

int main(int argc,char* argv[],char* envp[])
{
    char *s=NULL;
    int n=0;
    pid_t pid=fork();
    assert(pid!=-1);
    if(pid==0)
    {
        s="child";
        n=3;
    }
    else
    {
        s="parent";
        n=7;
    }
    for(int i=0;i 

(2)fork练习
#include
#include
#include
#include
#include

int main(int argc,char* argv[],char* envp[])
{
    for(int i=0;i<2;i++)
    {
        fork();
        printf("An");
    }
    exit(0);
}

打印6个A

#include
#include
#include
#include
#include

int main(int argc,char* argv[],char* envp[])
{
    for(int i=0;i<2;i++)
    {
        fork();
        printf("A");
    }
    exit(0);
}

打印8个A
没有n:把缓冲区放满或者程序结束时才打印

#include
#include
#include
#include
#include

int main(int argc,char* argv[],char* envp[])
{
    fork()||fork();
    printf("An");
    exit(0);
}

输出3个A

4. 僵死进程及处理方法

子进程先于父进程结束,父进程没有调用 wait 获取子进程退出码

解决方法:父进程通过调用wait()完成

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

int main(int argc,char* argv[],char* envp[])
{
    char *s=NULL;
    int n=0;
    pid_t pid=fork();
    assert(pid!=-1);
    if(pid==0)
    {
        s="child";
        n=3;
    }
    else
    {
        s="parent";
        n=7;
        int val=0;
        wait(&val);
        if(WIFEXITED(val))//判断程序是不是正常结束
        {
            printf("child exit code=%dn",WEXITSTATUS(val));//提前退出码
        }
    }
    for(int i=0;i 
5. 操作文件的系统调用 
(1)文件的读写 
#include
#include
#include
#include
#include
#include
int main()
{
    int fw=open("a.txt",O_WRONLY|O_CREAT,0600);
    assert(fw!=-1);
    write(fw,"hello",5);
    close(fw);

    int fr=open("a.txt",O_RDONLY);
    assert(fr!=-1);
    char buff[128]={0};
    int n=read(fr,buff,127);
    printf("buff=%s,n=%dn",buff,n);
    close(fr);
    
}


(2)完成对普通文件的复制
#include
#include
#include
#include
#include
#include
int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        printf("arg errn");
        return 0;
    }
    char *filename=argv[1];
    char *newfilename=argv[2];
    int fdr=open(filename,O_RDONLY);
    int fdw=open(newfilename,O_WRONLY|O_CREAT,0600);
    if(fdr==-1||fdw==-1)
    {
        printf("open file failedn");
        return 0;
    }
    char buff[512]={0};
    int n=0;
    while((n=read(fdr,buff,512))>0)
    {
        write(fdw,buff,n);
    }
    close(fdr);
    close(fdw);
}
6. 系统调用和库函数的区别

区别: 系统调用的实现在内核中,属于内核空间,库函数的实现在函数库中,属于用户空间。

每个进程都有自己的文件表,程序只要启动起来,默认情况下打开了三个文件:标准输入、标准输出和标准错误输出。

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

int main(int argc,char* argv[])
{
    int fd=open("file.txt",O_RDONLY);
    assert(fd!=-1);

    pid_t pid=fork();
    assert(pid!=-1);

    char buff[32]={0};
    if(pid==0)
    {
        read(fd,buff,1);
        printf("buff=%sn",buff);
        sleep(1);
        read(fd,buff,1);
        printf("buff=%sn",buff);
    }
    else
    {
        read(fd,buff,1);
        printf("buff=%sn",buff);
        sleep(1);
        read(fd,buff,1);
        printf("buff=%sn",buff);
    }
}

执行结果:



write()一定会直接打到屏幕上,而printf()会先存在缓冲区,等程序结束时再系统调用write()函数。

7. 进程替换

fork 和 exec 联合使用创建一个全新的进程

#include
#include
#include
#include
#include

int main(int argc,char* argv[],char* envp)
{
    char* myenvp[10]={"STR=hello"};
    char* myargv[10]={"ps","-f"};
   printf("main pid=%dn",getpid());
   //execl 执行成功不返回,直接从新程序的主函数开始执行,只有失败才返回错误码
   //execl("/usr/bin/ps","ps","-f",(char*)0);
   //execlp("ps","ps","-f",(char*)0);
   //execle("/usr/bin/ps","ps","-f",(char*)0,envp);
   
   //execv("/usr/bin/ps",myargv);
   //execvp("ps",myargv);

   execve("/usr/bin/ps",myargv,envp);
   printf("execl errn");

}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/334065.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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