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

简介: 嵌入式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结尾


0a2653c851af460fa595bd959398a8f1.png2d65d23f6d4748949b924e4057485923.png


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");
}

0a2653c851af460fa595bd959398a8f1.png


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");
}

0a2653c851af460fa595bd959398a8f1.png


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");
}

0a2653c851af460fa595bd959398a8f1.png


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");
}


0a2653c851af460fa595bd959398a8f1.png


三、vfork、system


3.1 vfok


2d65d23f6d4748949b924e4057485923.png

先执行子进程


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


vfork比fork更节省空间

只有遇到exec的时候,才会开辟新空间


3.2 system


0a2653c851af460fa595bd959398a8f1.png

相关文章
|
2天前
|
Java API 调度
[Java并发基础]多进程编程
[Java并发基础]多进程编程
|
3天前
|
NoSQL Linux 程序员
【linux进程信号(一)】信号的概念以及产生信号的方式
【linux进程信号(一)】信号的概念以及产生信号的方式
|
3天前
|
Linux
【linux进程间通信(一)】匿名管道和命名管道
【linux进程间通信(一)】匿名管道和命名管道
|
3天前
|
Java Shell Linux
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?
【linux进程控制(三)】进程程序替换--如何自己实现一个bash解释器?
|
3天前
|
算法 Linux Shell
【linux进程(二)】如何创建子进程?--fork函数深度剖析
【linux进程(二)】如何创建子进程?--fork函数深度剖析
|
3天前
|
存储 Linux Shell
【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?
【linux进程(一)】深入理解进程概念--什么是进程?PCB的底层是什么?
|
4天前
|
消息中间件 Unix Linux
Linux的学习之路:17、进程间通信(1)
Linux的学习之路:17、进程间通信(1)
19 1
|
1月前
|
消息中间件 Linux
Linux进程间通信(IPC)教程 Linux共享内存介绍:介绍POSIX共享内存的基本概念、用途和编程实践
Linux进程间通信(IPC)教程 Linux共享内存介绍:介绍POSIX共享内存的基本概念、用途和编程实践
25 2
|
1月前
|
消息中间件 存储 安全
Linux 进程和线程介绍:介绍Linux系统中进程和线程的基本概念、执行方式和相互关系
Linux 进程和线程介绍:介绍Linux系统中进程和线程的基本概念、执行方式和相互关系
34 1
Linux 进程和线程介绍:介绍Linux系统中进程和线程的基本概念、执行方式和相互关系
|
3月前
|
存储 缓存 Linux
『 Linux 』进程地址空间概念
『 Linux 』进程地址空间概念