一、進程間通信概述
進程間通信,即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
微信掃一掃
支付寶掃一掃