当前位置:   article > 正文

【linux系统】unix编程之进程(基础版)_printf("current pid %d\n",getpid());printf(fork pi

printf("current pid %d\n",getpid());printf(fork pid %d\n",fork());printf(fork pid %d\n",fork());return 0;

1.base

程序是存储在磁盘介质上的编译过的二进制文件

进程是程序跑起来的状态

程序是死的,进程是活的

进程是正在执行的程序的一个实例

malloc函数从内存的堆中分配储存

静态变量(通常是所说的程序中的全局变量)会使得线程化的程序不安全,除非保证各个线程访问时是互斥的!!

pid每个进程都有一个id和一个父进程id

获取进程pid/father pid getpid/getppid

2.进程状态

image-20200526181954409

就绪的进程就是非阻塞的

阻塞态不会直接去运行

阻塞时不会占用cpu

3.进程创建fork函数

进程可以通过调用fork函数来创建,调用进程称为父进程

fork函数会复制父进程的内存映像,新进程会收到父进程地址空间的一份copy

fork函数在子进程中返回0

#include<stdio.h>
#include<unistd.h>

int main(){
    int pid;
    printf("before fork()...\n");
    if((pid = fork()) < 0) perror("fork");
    if(pid == 0) printf("In child\n");
    else{
        sleep(1);
        printf("In parent\n");
    }
    printf("end fork\n");
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

image-20210311152358648

#include<stdio.h>
#include<unistd.h>

int main(){
    int pid;
    printf("before fork()...");
    if((pid = fork()) < 0) perror("fork");
    if(pid == 0) printf("\nIn child\n");
    else{
        sleep(1);
        printf("\nIn parent\n");
    }
    printf("end fork\n");
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

image-20210311152442842

为什么before fork()…输出了两次??

printf()底层是write实现的,行缓冲,当进行到程序的第6行时没有换行

当程序将数据提交给内核时,内核没有看到换行会以为后面还有数据(行缓冲优化)

fork()之后,两个进程的输出缓冲区都有befoe fork,当两个进程的输出缓冲区都读入到换行时进行输出

创建10个子进程

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>


int main(){
    int pid, x;
    for(int i = 1; i <= 10; i++){
        if((pid = fork()) < 0){
            perror("fork");
            continue;
        }
        if(pid == 0){
            x = i;
            break;
        }
    }
    printf("x = %d\n", x);
    sleep(1);

    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

4.等待函数wait

wait函数等待某进程结束

父进程可以通过wait函数一直阻塞到子进程结束

wait(NULL)可以等待当前进程任意一个子进程结束

image-20210311161257082

#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(){
    int pid;
    printf("before fork()...\n");
    if((pid = fork()) < 0) perror("fork");
    if(pid == 0) printf("In child\n");
    else{
        wait(NULL);
        printf("In parent\n");
    }
    printf("end fork\n");
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>

int main(){
    int pid;
    for(int i = 1; i <= 5; i++){
        if((pid = fork()) < 0) perror("fork");
        if(pid == 0){
            printf("I'm a child\n");
            return 0;
        }
    }
    //wait(NULL);
    for(int i = 1; i <= 5; i++){
    wait(NULL);
	}
    printf("I'm parent\n");
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

只wait了一次 所有parent不一定最后执行,要wait 5次才行

5.覆盖函数exec

fork()函数创建了调用程序的一份copy,但很多子程序要求执行不同的代码,exec函数提供了新映像覆盖调用进程映像的功能

The exec() family of functions replaces the current process image with a new process image.

用fork-exec方法使子进程执行新程序,父进程执行原程序

#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>

int main(){
    int pid;
    if((pid = fork()) < 0) perror("fork");
    if(pid == 0){
        execl("/bin/ls", "ls", "-l", NULL);//之后的程序子进程就没有了 execl已经替换了
        perror("child failed to exec ls");
        return 1;
    }
    wait(NULL);
    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

git commit不加-m选项时:

fork()一个子进程,子进程打开一个vim 保存退出后 父进程读取刚刚写的命令继续执行后续命令

task:a.out a.c

打开a.c文件(没有的话创建一个),编辑保存退出后编译这个文件,编译成功后执行,最后退出

 ************************************************************************/
//task:a.out a.c
//打开a.c文件(没有的话创建一个),编辑保存退出后编译这个文件,编译成功后执行,最后退出

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
int main(int argc, char **argv){
    pid_t pid;
    char filename[512] = {0};
    char o_name[512] = {0};//编译后的文件名称
    char f_type[256] = {0};
    char cmd[512] = {0};
    if(argc < 2){
        fprintf(stderr, "Usage: %s filename arg...\n", argv[0]);
        return 1;
    }
    strcpy(filename, argv[1]);
    
    char *sub = NULL;//找到.的位置 逆序找到最后一个.
    if((sub = strrchr(filename, '.')) == NULL){
        fprintf(stderr, "Not support File type!\n");
        return 2;
    }
    strncpy(o_name, filename, sub - filename);
    strcpy(f_type, sub);
    
    if(!strcmp(f_type, ".c")){
        strcpy(cmd, "gcc");
    }else if(!strcmp(f_type, ".cpp")){
        strcpy(cmd, "g++");
    }else{
        fprintf(stderr, "Not support File type\n");
        return 2;
    }
    if((pid = fork()) < 0){
        perror("fork");
        return 3;
    }
    
    if(pid == 0){
        execlp("vim", "vim", filename, NULL);
    }
    wait(NULL);
    
    if((pid = fork()) < 0){
        perror("fork");
        return 3;
    }
    if(pid == 0){
        execlp(cmd, cmd, filename, "-o", o_name, NULL);
    }

    int status;
    wait(&status);
    //status = 0表示子进程执行成功
    if(status == 0){
        char exe_cmd[50] = {0};
        sprintf(exe_cmd, "./%s", o_name);
        execlp(exe_cmd, o_name, NULL);//./a.out
    }else{
        printf("compile Failed!\n");
        return 4;
    }

    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

https://www.cnblogs.com/mickole/p/3187409.html

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号