在Ubuntu系统中,进程间通信(IPC)可以通过多种方式实现,以下是一些常见的IPC方法:
管道(Pipes):
消息队列(Message Queues):
共享内存(Shared Memory):
信号(Signals):
信号量(Semaphores):
套接字(Sockets):
内存映射文件(Memory-mapped Files):
下面是一些简单的示例,展示如何在Ubuntu中使用这些IPC机制:
匿名管道示例:
#include <stdio.h>
#include <unistd.h>
int main() {
int pipefd[2];
char buffer[10];
// 创建匿名管道
if (pipe(pipefd) == -1) {
perror("pipe");
return 1;
}
// 创建子进程
pid_t pid = fork();
if (pid == -1) {
perror("fork");
return 1;
}
if (pid == 0) { // 子进程
close(pipefd[1]); // 关闭写端
read(pipefd[0], buffer, sizeof(buffer)); // 读取消息
printf("Child received: %s\n", buffer);
close(pipefd[0]);
} else { // 父进程
close(pipefd[0]); // 关闭读端
write(pipefd[1], "Hello from parent!", 20); // 发送消息
close(pipefd[1]);
wait(NULL); // 等待子进程结束
}
return 0;
}
命名管道(FIFO)示例:
# 创建命名管道
mkfifo myfifo
# 写入数据到命名管道
echo "Hello FIFO" > myfifo &
# 从命名管道读取数据
cat myfifo
共享内存示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main() {
key_t key = ftok("shmfile", 65);
int shmid = shmget(key, 1024, 0666|IPC_CREAT);
char *str = (char*) shmat(shmid, (void*)0, 0);
strcpy(str, "Hello shared memory");
printf("Shared memory: %s\n", str);
shmdt(str);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
信号量示例:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/sem.h>
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
int main() {
key_t key = ftok("semfile", 65);
int semid = semget(key, 1, 0666|IPC_CREAT);
union semun arg;
arg.val = 1; // 初始化信号量为1
semctl(semid, 0, SETVAL, arg);
// 使用semop进行P操作(等待信号量)
struct sembuf sb = {0, -1, SEM_UNDO};
semop(semid, &sb, 1);
printf("Semaphore value: %d\n", semctl(semid, 0, GETVAL, arg));
// 使用semop进行V操作(释放信号量)
sb.sem_op = 1;
semop(semid, &sb, 1);
semctl(semid, 0, IPC_RMID, arg);
return 0;
}
套接字示例:
// Unix Domain Sockets 示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
int main() {
int sockfd;
struct sockaddr_un addr;
char buffer[1024];
// 创建套接字
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket");
return 1;
}
// 设置地址结构
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, "/tmp/uds.sock", sizeof(addr.sun_path)-1);
// 绑定套接字
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("bind");
return 1;
}
// 监听连接
listen(sockfd, 5);
// 接受连接
int clientfd = accept(sockfd, NULL, NULL);
if (clientfd == -1) {
perror("accept");
return 1;
}
// 读取数据
read(clientfd, buffer, sizeof(buffer));
printf("Received: %s\n", buffer);
// 发送数据
write(clientfd, "Hello from server!", 20);
// 关闭套接字
close(clientfd);
close(sockfd);
return 0;
}
这些示例展示了如何在Ubuntu中使用不同的IPC机制。在实际应用中,你需要根据具体需求选择合适的IPC方法,并编写相应的代码。记得在编译C程序时链接必要的库,例如-lrt
用于实时库,-lpthread
用于线程支持等。