在Ubuntu系统中,有多种高效的进程间通信(IPC)方法可供选择。以下是一些常用的IPC方法:
fcntl系统调用实现文件级别的锁定,防止多个进程同时修改同一文件。epoll、kqueue等机制监听多个文件描述符的事件,实现高效的I/O多路复用。选择哪种IPC方法取决于具体的应用场景和需求:
以下是一些简单的示例代码,展示如何在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]);
}
return 0;
}
#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 World");
printf("String written to shared memory: %s\n", str);
shmdt(str);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
// 服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
int main() {
int server_fd, new_socket;
struct sockaddr_un address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
if ((server_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
address.sun_family = AF_UNIX;
strncpy(address.sun_path, "/tmp/uds_example.sock", sizeof(address.sun_path)-1);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
read(new_socket, buffer, 1024);
printf("Message from client: %s\n", buffer);
close(new_socket);
close(server_fd);
return 0;
}
// 客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
int main() {
struct sockaddr_un serv_addr;
int sock = 0;
char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sun_family = AF_UNIX;
strncpy(serv_addr.sun_path, "/tmp/uds_example.sock", sizeof(serv_addr.sun_path)-1);
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
send(sock, hello, strlen(hello), 0);
printf("Hello message sent\n");
read(sock, buffer, 1024);
printf("Message from server: %s\n", buffer);
close(sock);
return 0;
}
这些示例代码展示了如何在Ubuntu中使用管道、共享内存和Unix域套接字进行进程间通信。根据具体需求选择合适的IPC方法,并参考相应的API文档进行实现。