一、進程間通信概述
進程間通信,即Inter-Process Communication(IPC),是指不同進程之間進行信息交換和共享的機制。在Linux系統下,IPC有多種方法,包括管道、套接字、消息隊列、共享內存等。
管道:是一種單向通信機制,只能在父子進程之間共享數據,並且只能用於有親緣關係的進程間通信。使用C語言實現的例子:
#include <stdio.h> #include <unistd.h> #define BUFFER_SIZE 25 #define READ_END 0 #define WRITE_END 1 int main(void) { char write_msg[BUFFER_SIZE] = "Hello, world!"; char read_msg[BUFFER_SIZE]; int fd[2]; pid_t pid; if (pipe(fd) == -1) { fprintf(stderr, "Pipe failed"); return 1; } pid = fork(); if (pid 0) { close(fd[READ_END]); write(fd[WRITE_END], write_msg, strlen(write_msg)+1); close(fd[WRITE_END]); } else { close(fd[WRITE_END]); read(fd[READ_END], read_msg, BUFFER_SIZE); printf("Received message: %s\n", read_msg); close(fd[READ_END]); } return 0; }
套接字:是一種雙向通信機制,可以在不同的進程之間進行信息交換。可以分為面向連接(TCP)和無連接(UDP)套接字。使用Python實現的例子:
import socket HOST = '127.0.0.1' PORT = 12345 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen(1) conn, addr = s.accept() with conn: print('Connected by', addr) while True: data = conn.recv(1024) if not data: break conn.sendall(data)
消息隊列:是內核維護的一種隊列,進程可以在隊列中發送和接收消息。使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSGSZ 128 typedef struct msgbuf { long mtype; char mtext[MSGSZ]; } message_buf; int main() { int msqid; key_t key; message_buf rbuf; size_t buflen; key = ftok("msgq.txt", 'A'); msqid = msgget(key, 0666 | IPC_CREAT); rbuf.mtype = 1; sprintf(rbuf.mtext, "Hello, world!"); buflen = strlen(rbuf.mtext) + 1; msgsnd(msqid, &rbuf, buflen, IPC_NOWAIT); msgrcv(msqid, &rbuf, MSGSZ, 1, 0); printf("Received message: %s\n", rbuf.mtext); msgctl(msqid, IPC_RMID, NULL); return 0; }
共享內存:是多個進程共享同一塊物理內存的機制。使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #define SHMSZ 27 int main() { int shmid; key_t key; char *shm, *s; key = ftok("shmfile", 'A'); shmid = shmget(key, SHMSZ, 0666 | IPC_CREAT); shm = shmat(shmid, NULL, 0); s = shm; for (char c = 'a'; c <= 'z'; c++) { *s++ = c; } *s = '\0'; while (*shm != '*') { sleep(1); } shmdt(shm); shmctl(shmid, IPC_RMID, NULL); return 0; }
二、信號量機制
信號量(Semaphore)是一種保證多個進程之間互斥訪問共享資源的機制。多個進程可以在信號量上進行等待和喚醒操作,並互相通知。在Linux系統下,信號量可以使用System V IPC 或 POSIX IPC實現。
System V IPC實現信號量,使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/sem.h> union semun { int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf; }; int main() { int sem_id; key_t key; struct sembuf sembuf; union semun arg; key = ftok("semfile", 'A'); sem_id = semget(key, 1, 0666 | IPC_CREAT); arg.val = 1; semctl(sem_id, 0, SETVAL, arg); sembuf.sem_num = 0; sembuf.sem_op = -1; sembuf.sem_flg = SEM_UNDO; semop(sem_id, &sembuf, 1); printf("Semaphore locked!\n"); sembuf.sem_op = 1; semop(sem_id, &sembuf, 1); printf("Semaphore unlocked!\n"); semctl(sem_id, 0, IPC_RMID); return 0; }
POSIX IPC也可以實現信號量機制,使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <semaphore.h> #define SEM_NAME "/mysem" int main() { sem_t *sem; sem = sem_open(SEM_NAME, O_CREAT, 0666, 1); sem_wait(sem); printf("Semaphore locked!\n"); sem_post(sem); printf("Semaphore unlocked!\n"); sem_unlink(SEM_NAME); sem_close(sem); return 0; }
三、共享內存機制
共享內存是一種高效的進程間通信機制,多個進程可以將同一塊物理內存映射到自己的地址空間中,實現共享。在Linux系統下,共享內存可以使用System V IPC或 POSIX IPC實現。
System V IPC實現共享內存,使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h> #define SHMSZ 27 int main() { int shmid; key_t key; char *shm, *s; key = ftok("shmfile", 'A'); shmid = shmget(key, SHMSZ, 0666 | IPC_CREAT); shm = shmat(shmid, NULL, 0); s = shm; for (char c = 'a'; c <= 'z'; c++) { *s++ = c; } *s = '\0'; while (*shm != '*') { sleep(1); } shmdt(shm); shmctl(shmid, IPC_RMID, NULL); return 0; }
POSIX IPC也可以實現共享內存機制,使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/mman.h> #define SHMSZ 27 int main() { int fd; char *shm, *s; fd = shm_open("shmfile", O_CREAT | O_RDWR, 0666); ftruncate(fd, SHMSZ); shm = mmap(NULL, SHMSZ, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); s = shm; for (char c = 'a'; c <= 'z'; c++) { *s++ = c; } *s = '\0'; while (*shm != '*') { sleep(1); } munmap(shm, SHMSZ); shm_unlink("shmfile"); return 0; }
四、消息隊列機制
消息隊列是一種專門用於進程間通信的機制,多個進程可以通過消息隊列發送和接收消息。在Linux系統下,消息隊列可以使用System V IPC或 POSIX IPC實現。
System V IPC實現消息隊列,使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSGSZ 128 typedef struct msgbuf { long mtype; char mtext[MSGSZ]; } message_buf; int main() { int msqid; key_t key; message_buf rbuf; size_t buflen; key = ftok("msgq.txt", 'A'); msqid = msgget(key, 0666 | IPC_CREAT); rbuf.mtype = 1; sprintf(rbuf.mtext, "Hello, world!"); buflen = strlen(rbuf.mtext) + 1; msgsnd(msqid, &rbuf, buflen, IPC_NOWAIT); msgrcv(msqid, &rbuf, MSGSZ, 1, 0); printf("Received message: %s\n", rbuf.mtext); msgctl(msqid, IPC_RMID, NULL); return 0; }
POSIX IPC也可以實現消息隊列機制,使用C語言實現的例子:
#include <stdio.h> #include <stdlib.h> #include <mqueue.h> #define QUEUE_NAME "/test_queue" #define MSGSZ 128 int main() { mqd_t qd; char msgbuf[MSGSZ]; struct mq_attr attr; attr.mq_flags = 0; attr.mq_maxmsg = 10; attr.mq_msgsize = MSGSZ; attr.mq_curmsgs = 0; qd = mq_open(QUEUE_NAME, O_CREAT | O_RDWR, 0666, &attr); mq_send(qd, "Hello, world!", 13, 0); mq_receive(qd, msgbuf, MSGSZ, NULL); printf("Received message: %s\n", msgbuf); mq_close(qd); mq_unlink(QUEUE_NAME); return 0; }
五、總結
Linux IPC提供了多種機制用於進程間通信,包括管道、套接字、消息隊列、共享內存和信號量。任何一種IPC機制都可以被應用於相應的場景中。
原創文章,作者:SDTSW,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/368220.html