在Ubuntu系统中,有多种方法可以实现进程间的数据共享。以下是一些常用的方法:
管道是一种半双工的通信方式,通常用于父子进程之间的通信。
#include <stdio.h>
#include <unistd.h>
int main() {
int pipefd[2];
pid_t pid;
char buffer[10];
if (pipe(pipefd) == -1) {
perror("pipe");
return 1;
}
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", 18);
close(pipefd[1]);
}
return 0;
}
命名管道是一种特殊的文件,可以在不相关的进程之间进行通信。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main() {
int fd;
char buffer[10];
mkfifo("myfifo", 0666);
fd = open("myfifo", O_RDWR);
if (fd == -1) {
perror("open");
return 1;
}
write(fd, "Hello from FIFO", 18);
read(fd, buffer, sizeof(buffer));
printf("Received: %s\n", buffer);
close(fd);
unlink("myfifo");
return 0;
}
共享内存是一种高效的进程间通信方式,允许多个进程访问同一块内存区域。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
int main() {
key_t key = 1234;
int shmid;
char *str;
// 创建或获取共享内存段
shmid = shmget(key, 100, IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
return 1;
}
// 将共享内存段附加到进程地址空间
str = (char *)shmat(shmid, NULL, 0);
if (str == (char *)-1) {
perror("shmat");
return 1;
}
strcpy(str, "Hello from shared memory");
printf("Shared memory message: %s\n", str);
// 分离共享内存段
shmdt(str);
// 删除共享内存段
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
消息队列是一种允许进程发送和接收消息的机制。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msg_buffer {
long mtype;
char mtext[100];
};
int main() {
key_t key = 1234;
int msgid;
struct msg_buffer message;
// 创建或获取消息队列
msgid = msgget(key, IPC_CREAT | 0666);
if (msgid == -1) {
perror("msgget");
return 1;
}
message.mtype = 1;
strcpy(message.mtext, "Hello from message queue");
// 发送消息
if (msgsnd(msgid, &message, sizeof(message.mtext), 0) == -1) {
perror("msgsnd");
return 1;
}
// 接收消息
if (msgrcv(msgid, &message, sizeof(message.mtext), 1, 0) == -1) {
perror("msgrcv");
return 1;
}
printf("Received message: %s\n", message.mtext);
// 删除消息队列
msgctl(msgid, IPC_RMID, NULL);
return 0;
}
信号量用于进程同步,可以用来控制对共享资源的访问。
#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;
};
int main() {
key_t key = 1234;
int semid;
union semun arg;
// 创建或获取信号量集
semid = semget(key, 1, IPC_CREAT | 0666);
if (semid == -1) {
perror("semget");
return 1;
}
// 初始化信号量
arg.val = 1;
if (semctl(semid, 0, SETVAL, arg) == -1) {
perror("semctl");
return 1;
}
// 执行临界区代码
printf("Entering critical section\n");
sleep(1);
printf("Exiting critical section\n");
// 删除信号量集
semctl(semid, 0, IPC_RMID);
return 0;
}
这些方法各有优缺点,选择哪种方法取决于具体的应用场景和需求。