嵌入式Linux C多进程编程(四)——进程创建

一、进程的创建(实例:读写鼠标键盘)

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    pid_t pid;

    pid = fork();

    if (pid < 0)
    {
        perror("fork error!");
        exit(1);
    }

    if (pid > 0)
    {
        int fd = open("/dev/input/mouse0", O_RDWR);
        int cor = 0;
        while (1)
        {
            read(fd, &cor, sizeof(cor));
            //sleep(1);
            printf("cor = %d\n", cor);
        }
        
    }
    if (pid == 0)
    {
        char buffer[1024];
        while (1)
        {
            memset(buffer, 0, sizeof(buffer));
            int n_r = read(0, buffer, sizeof(buffer) - 1);
            buffer[n_r] = '\0';
            printf("buffer = %s\n", buffer);
        }
    }

    return 0;
}

同一文件,进程的读写位置不同,读写位置不被共享
如果在创建进程前,打开文件,则读写位置被共享

二、exec函数族

在一个进程中调用里一个程序
调用之后,原文件下面的程序会被覆盖,不予执行
要以NULL结尾

在这里插入图片描述

在这里插入图片描述

2.1 execl

int execl (const char *path, const char *arg, ..);

2.1.1 demo.c

demo

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

int main(int argc, char const *argv[])
{
    for (size_t i = 0; i < argc; i++)
    {
        printf("argc[%ld] = %s\n", i, argv[i]);
    }
    
    pid_t pid = getpid();
    pid_t ppid = getppid();

    printf("pid = %d\n",pid);
    printf("ppid = %d\n",ppid);

    char buffer[1024];
    int n_r = read(0, buffer, sizeof(1024) - 1);
    buffer[n_r] = '\0';
    printf("buffer = %s\n", buffer);
    return 0;
}

2.1.2 execl.c

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

int main(int argc, char const *argv[])
{
    printf("hello world\n");
    execl("./demo","./demo","xasxa","hahaha",NULL);

    printf("快乐暑假\n");
}

在这里插入图片描述

2.2 execv

int execv (const char *path, char *const argv[]);

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

int main(int argc, char const *argv[])
{
    printf("hello world\n");
    //execl("./demo","./demo","xasxa","hahaha",NULL);

    char *arg[] = {"./demo", "hello1", "hello2", NULL};
    execv("./demo", arg);

    printf("快乐暑假\n");
}

在这里插入图片描述

2.3 execlp

int execIp (const char *file, const char *arg,...)

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

int main(int argc, char const *argv[])
{
    printf("hello world\n");
    //execl("./demo","./demo","xasxa","hahaha",NULL);

    //char *arg[] = {"./demo", "hello1", "hello2", NULL};
    //execv("./demo", arg);

    execlp("/home/jsetc/2022.7c++/多进程/demo","./demo","world1","world2",NULL);

    printf("快乐暑假\n");
}

在这里插入图片描述

2.4 execvpe

int execvpe (const char *file, char *const argv[], char *const envp[);

env是环境变量

2.4.1 demo.c

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

int main(int argc, char const *argv[], char **env)
{
    for (size_t i = 0; i < argc; i++)
    {
        printf("argc[%ld] = %s\n", i, argv[i]);
    }
    for (size_t i = 0; i < argc; i++)
    {
        printf("env[%ld] = %s\n", i, env[i]);
    }
    
    pid_t pid = getpid();
    pid_t ppid = getppid();

    printf("pid = %d\n",pid);
    printf("ppid = %d\n",ppid);

    char buffer[1024];
    int n_r = read(0, buffer, sizeof(1024) - 1);
    buffer[n_r] = '\0';
    printf("buffer = %s\n", buffer);
    return 0;
}

2.4.2 execvpe

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

int main(int argc, char const *argv[])
{
    printf("hello world\n");
    //execl("./demo","./demo","xasxa","hahaha",NULL);

    char *arg[] = {"./demo", "hello1", "hello2", NULL};
    char *env[] = {"UXAS = admin","PASSWD = 123","trytrytry",NULL};
    //execv("./demo", arg);

    //execlp("/home/jsetc/2022.7c++/多进程/demo","./demo","world1","world2",NULL);
    execvpe("/home/jsetc/2022.7c++/多进程/demo", arg, env);
    printf("快乐暑假\n");
}

在这里插入图片描述

三、vfork、system

3.1 vfok

在这里插入图片描述

先执行子进程

如果没有exec,则会共享父进程资源,子进程一定要加exit(1)进行异常退出,不会造成二次释放

vfork比fork更节省空间
只有遇到exec的时候,才会开辟新空间

3.2 system

system()

posted @ 2022-07-12 21:38  周末不下雨  阅读(94)  评论(0编辑  收藏  举报