欢迎来到军工软件开发人才培养基地——学到牛牛

多进程的创建和销毁及进程间通信

时间:2024-05-06 07:01:10 来源:学到牛牛

​一、概述

多进程是指在一个程序中同时运行多个进程,每个进程都可以独立执行不同的任务。多进程可以提高程序的并发性和响应性,使得程序能够更加高效地利用计算机的资源。在C语言中,可以使用fork函数来创建新的进程。

二、进程的创建和销毁

在使用fork函数创建进程时,需要包含头文件unistd.h。进程的创建和销毁可以使用以下函数:

pid_t fork(void);

int wait(int *status);

int waitpid(pid_t pid, int *status, int options);

int exit(int status);

示例代码

#include <stdio.h>

#include <unistd.h>

int main()

{

    pid_t pid;

    int status;

 

    pid = fork();

    if (pid == 0) {

        printf("Child process\n");

        // 子进程执行的代码

        exit(0);

    } else if (pid > 0) {

        printf("Parent process\n");

        // 父进程执行的代码

        wait(&status);

    } else {

        printf("Failed to create child process\n");

    }

    return 0;

}

在上面的示例代码中,使用fork函数创建了一个新的进程。如果fork函数返回值为0,则表示当前进程为子进程,执行子进程的代码并使用exit函数结束进程;如果fork函数返回值大于0,则表示当前进程为子进程,执行子进程的代码并使用exit函数结束进程;如果fork函数返回值大于0,则表示当前进程为父进程,执行父进程的代码并使用wait函数等待子进程结束。如果fork函数返回值小于0,则表示创建进程失败。

三、进程间通信

在多进程编程中,不同的进程之间需要进行通信,以实现数据共享和协作等功能。在C语言中,可以使用管道(pipe)、共享内存(shared memory)、消息队列(message queue)等机制来实现进程间通信。

1、管道

管道是一种半双工的通信机制,用于在两个进程之间传递数据。在C语言中,可以使用pipe函数创建管道,使用read和write函数读写管道中的数据。以下是一个使用管道实现进程间通信的示例代码:

#include <stdio.h>

#include <unistd.h>

#include <string.h>

 

int main()

{

    int fd[2];

    pid_t pid;

    char buf[1024];

 

    if (pipe(fd) < 0) {

        printf("Failed to create pipe\n");

        return -1;

    }

 

    pid = fork();

    if (pid == 0) {

        close(fd[1]);

        read(fd[0], buf, sizeof(buf));

        printf("Child process received: %s\n", buf);

        close(fd[0]);

    } else if (pid > 0) {

        close(fd[0]);

        strcpy(buf, "Hello, child process!");

        write(fd[1], buf, strlen(buf));

        close(fd[1]);

    } else {

        printf("Failed to create child process\n");

        return -1;

    }

    return 0;

}

在上面的示例代码中,使用pipe函数创建了一个管道。在父进程中,使用write函数向管道中写入数据;在子进程中,使用read函数从管道中读取数据。需要注意的是,在使用管道时,需要先关闭不需要的文件描述符,以避免出现死锁等问题。

2、共享内存

共享内存是一种进程间通信的机制,用于在多个进程之间共享同一块内存区域。在C语言中,可以使用shmget函数创建共享内存,使用shmat函数将共享内存映射到进程的地址空间中,使用shmdt函数将共享内存从进程的地址空间中分离,使用shmctl函数控制共享内存的状态。以下是一个使用共享内存实现进程间通信的示例代码:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <string.h>

 

#define SHM_SIZE 1024

 

int main()

{

    int shmid;

    char *shmaddr;

    pid_t pid;

 

    shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);

    if (shmid < 0) {

        printf("Failed to create shared memory\n");

        return -1;

    }

 

    pid = fork();

    if (pid == 0) {

        shmaddr = shmat(shmid, NULL, 0);

        printf("Child process received: %s\n", shmaddr);

        shmdt(shmaddr);

    } else if (pid > 0) {

        shmaddr = shmat(shmid, NULL, 0);

        strcpy(shmaddr, "Hello, child process!");

        shmdt(shmaddr);

    } else {

        printf("Failed to create child process\n");

        return -1;

    }

 

    shmctl(shmid, IPC_RMID, NULL);

 

    return 0;

}

在上面的示例代码中,使用shmget函数创建了一个共享内存对象。在父进程中,使用shmat函数将共享内存映射到进程的地址空间中,并使用strcpy函数向共享内存中写入数据;在子进程中,使用shmat函数将共享内存映射到进程的地址空间中,并使用printf函数从共享内存中读取数据。需要注意的是,在使用共享内存时,需要使用IPC_PRIVATE作为key参数,以避免不同进程之间的冲突。