一、进程间通信概述
进程间通信,即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/n/368220.html
微信扫一扫
支付宝扫一扫