当前位置:实例文章 » JAVA Web实例» [文章]TCP/IP网络编程 第十一章:进程间通信

TCP/IP网络编程 第十一章:进程间通信

发布人:shili8 发布时间:2024-12-29 10:35 阅读次数:0

**TCP/IP网络编程**

**第十一章:进程间通信**

在前面的章节中,我们已经学习了如何使用TCP/IP协议进行网络通信。然而,在实际的应用场景中,往往需要多个进程或线程之间进行通信,以实现更复杂的功能。在本章中,我们将讨论如何在Linux系统上实现进程间通信。

**1.管道**

管道是一种最简单的进程间通信方式。它通过创建一个特殊类型的文件来实现通信,两个进程可以通过读写这个文件来交换信息。

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

int main() {
 int pipefd[2];
 if (pipe(pipefd) == -1) {
 perror("pipe");
 exit(EXIT_FAILURE);
 }

 pid_t pid = fork();
 if (pid == -1) {
 perror("fork");
 exit(EXIT_FAILURE);
 }

 if (pid ==0) { // 子进程 close(pipefd[0]); // 关闭读管道 char buffer[10];
 read(pipefd[1], buffer,10); // 从父进程读取信息 printf("子进程收到信息:%s
", buffer);
 close(pipefd[1]); // 关闭写管道 } else { // 父进程 close(pipefd[1]); // 关闭写管道 char buffer[] = "Hello, world!";
 write(pipefd[0], buffer,10); // 向子进程写入信息 printf("父进程发送信息:%s
", buffer);
 close(pipefd[0]); // 关闭读管道 }

 return0;
}


在上面的例子中,我们使用`pipe()`函数创建一个管道,两个进程通过`fork()`函数创建后,可以通过读写这个管道来交换信息。

**2.命名管道**

命名管道是一种特殊类型的文件,它可以被多个进程共享。每个进程都可以打开这个文件,并使用它来进行通信。

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

int main() {
 int fd;
 char *pathname = "/tmp/named_pipe";

 if ((fd = open(pathname, O_RDWR | O_CREAT,0666)) == -1) {
 perror("open");
 exit(EXIT_FAILURE);
 }

 pid_t pid = fork();
 if (pid == -1) {
 perror("fork");
 exit(EXIT_FAILURE);
 }

 if (pid ==0) { // 子进程 char buffer[10];
 read(fd, buffer,10); // 从父进程读取信息 printf("子进程收到信息:%s
", buffer);
 close(fd); // 关闭文件描述符 } else { // 父进程 char buffer[] = "Hello, world!";
 write(fd, buffer,10); // 向子进程写入信息 printf("父进程发送信息:%s
", buffer);
 close(fd); // 关闭文件描述符 }

 return0;
}


在上面的例子中,我们使用`open()`函数创建一个命名管道,每个进程都可以打开这个文件,并使用它来进行通信。

**3.信号**

信号是一种特殊类型的事件,它可以被多个进程共享。每个进程都可以注册一个信号处理函数,以便在接收到该信号时执行特定的操作。

c#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void sigint_handler(int signum) {
 printf("子进程收到SIGINT信号
");
}

int main() {
 pid_t pid = fork();
 if (pid == -1) {
 perror("fork");
 exit(EXIT_FAILURE);
 }

 if (pid ==0) { // 子进程 signal(SIGINT, sigint_handler); // 注册SIGINT信号处理函数 while (1) {
 sleep(1);
 }
 } else { // 父进程 printf("父进程发送SIGINT信号
");
 kill(pid, SIGINT); // 向子进程发送SIGINT信号 }

 return0;
}


在上面的例子中,我们使用`signal()`函数注册一个信号处理函数,以便在接收到SIGINT信号时执行特定的操作。

**4.共享内存**

共享内存是一种特殊类型的文件,它可以被多个进程共享。每个进程都可以打开这个文件,并使用它来进行通信。

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

int main() {
 int *shared_memory;
 shared_memory = (int *)malloc(sizeof(int));
 if (!shared_memory) {
 perror("malloc");
 exit(EXIT_FAILURE);
 }

 pid_t pid = fork();
 if (pid == -1) {
 perror("fork");
 exit(EXIT_FAILURE);
 }

 if (pid ==0) { // 子进程 *shared_memory =10;
 printf("子进程写入共享内存:%d
", *shared_memory);
 } else { // 父进程 printf("父进程读取共享内存:%d
", *shared_memory);
 }

 free(shared_memory); //释放共享内存 return0;
}


在上面的例子中,我们使用`malloc()`函数创建一个共享内存,每个进程都可以打开这个文件,并使用它来进行通信。

**5.消息队列**

消息队列是一种特殊类型的文件,它可以被多个进程共享。每个进程都可以打开这个文件,并使用它来进行通信。

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

int main() {
 int queue_id;
 char *pathname = "/tmp/msg_queue";

 if ((queue_id = msgget(pathname,0666 | IPC_CREAT)) == -1) {
 perror("msgget");
 exit(EXIT_FAILURE);
 }

 pid_t pid = fork();
 if (pid == -1) {
 perror("fork");
 exit(EXIT_FAILURE);
 }

 if (pid ==0) { // 子进程 struct msgbuf message;
 message.mtype =10;
 strcpy(message.mtext, "Hello, world!");
 if (msgsnd(queue_id, &message, strlen(message.mtext), IPC_NOWAIT) == -1) {
 perror("msgsnd");
 exit(EXIT_FAILURE);
 }
 } else { // 父进程 struct msgbuf message;
 if (msgrcv(queue_id, &message,10,0, IPC_NOWAIT) == -1) {
 perror("msgrcv");
 exit(EXIT_FAILURE);
 }
 printf("父进程收到消息:%s
", message.mtext);
 }

 return0;
}


在上面的例子中,我们使用`msgget()`函数创建一个消息队列,每个进程都可以打开这个文件,并使用它来进行通信。

**6.信号量**

信号量是一种特殊类型的变量,它可以被多个进程共享。每个进程都可以对该变量进行操作,以便在满足特定条件时执行特定的操作。

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

int main() {
 int sem_id;
 if ((sem_id = semget(0,1, IPC_CREAT |0666)) == -1) {
 perror("semget");
 exit(EXIT_FAILURE);
 }

 pid_t pid = fork();
 if (pid == -1) {
 perror("fork");
 exit(EXIT_FAILURE);
 }

 if (pid ==0) { // 子进程 struct sembuf semaphore;
 semaphore.sem_num =0;
 semaphore.sem_op =0; // P操作 semaphore.sem_flg = IPC_NOWAIT;
 if (semop(sem_id, &semaphore,1) == -1) {
 perror("semop");
 exit(EXIT_FAILURE);
 }
 } else { // 父进程 struct sembuf semaphore;
 semaphore.sem_num =0;
 semaphore.sem_op =1; // V操作 semaphore.sem_flg = IPC_NOWAIT;
 if (semop(sem_id, &semaphore,1) == -1) {
 perror("semop");
 exit(EXIT_FAILURE);
 }
 }

 return0;
}


在上面的例子中,我们使用`semget()`函数创建一个信号量,每个进程都可以对该变量进行操作,以便在满足特定条件时执行特定的操作。

**7.共享内存**

共享内存是一种特殊类型的文件,它可以被多个进程共享。每个进程都可以打开这个文件,并使用它来进行通信。

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

int main() {
 int *shared

其他信息

其他资源

Top