Linux进程间通信(IPC, Inter-Process Communication)包括了多种不同的技术,例如管道(pipe)、信号(signal)、共享内存(shared memory)、消息队列(message queues)、信号量(semaphores)以及套接字(sockets)等。以下将针对每种通信方式给出简单的代码实例来进行说明。
- 管道(Pipe)
管道是最基本的IPC机制之一,这里指匿名管道,允许一个进程和另一个进程之间的单向数据流。这通常用于父进程与子进程之间的通信。
#include <stdio.h>
#include <unistd.h>
int main() {
int pipefd[2];
pid_t cpid;
char buf;
if (pipe(pipefd) == -1) {
perror("pipe");
return 1;
}
cpid = fork();
if (cpid == -1) {
perror("fork");
return 1;
}
if (cpid == 0) { /* 子进程读取端 */
close(pipefd[1]); /* 关闭写端 */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
} else { /* 父进程写入端 */
close(pipefd[0]); /* 关闭读端 */
write(pipefd[1], "示例消息", 8);
close(pipefd[1]);
wait(NULL); /* 等待子进程 */
}
return 0;
}
- 信号(Signal)
信号是一种软件中断机制,用于处理异步事件或通知进程发生了某个事件。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void sighandler(int signum) {
printf("捕获信号 %d\n", signum);
exit(1);
}
int main () {
signal(SIGINT, sighandler);
while(1) {
printf("开始睡眠...\n");
sleep(1);
}
return(0);
}
- 共享内存(Shared Memory)
共享内存允许两个或两个以上的进程共享一个给定的存储区。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main() {
int shmid;
key_t key = 5678;
char *data;
shmid = shmget(key, 1024, IPC_CREAT | 0666);
if (shmid < 0) {
perror("shmget");
exit(1);
}
data = shmat(shmid, NULL, 0);
if (data == (char *)(-1)) {
perror("shmat");
exit(1);
}
memcpy(data, "这是共享内存的示例", 18);
printf("写入: %s\n", data);
return 0;
}
- 消息队列(Message Queue)
消息队列是消息的链接列表,存储在内核中并由消息队列标识符标识。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msg_buf {
long msg_type;
char msg_text[100];
};
int main() {
struct msg_buf msg;
int msgid;
key_t key;
key = 1234;
msgid = msgget(key, 0666 | IPC_CREAT);
msg.msg_type = 1;
printf("写入消息: ");
fgets(msg.msg_text, 100, stdin);
msgsnd(msgid, &msg, sizeof(msg), 0);
return 0;
}
- 信号量(Semaphore)
信号量主要用于同步进程对公共资源的访问。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main() {
key_t key = 1234;
int semid;
struct sembuf sb = {0, -1, 0}; // 设置信号量操作
semid = semget(key, 1, 0666 | IPC_CREAT);
// P操作
if (semop(semid, &sb, 1) == -1) {
perror("semop");
exit(1);
}
printf("成功进入临界区\n");
sb.sem_op = 1; // V操作
if (semop(semid, &sb, 1) == -1) {
perror("semop");
exit(1);
}
return 0;
}
- 套接字(Sockets)
套接字允许在同一台计算机上的进程或不同计算机上的进程之间进行通信。
// TCP套接字示例: 简单服务器端
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
server_fd = socket(AF_INET, SOCK_STREAM, 0);
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(8080);
bind(server_fd, (struct sockaddr *)&address, sizeof(address));
listen(server_fd, 3);
new_socket = accept(server_fd, (struct sockaddr *)&address, &addrlen);
return 0;
}