在Linux系統中,System V IPC(Inter-Process Communication)提供了一系列進程間通信的機制,包括共享內存、消息隊列和信號量。這些機制在系統中發揮了重要作用,幫助進程之間進行數據交換和同步。本文將詳細介紹這些機制的概念、使用方法以及應用場景。
一、共享內存
1.1 概念
共享內存(Shared Memory)是最快的一種進程間通信方式,它允許多個進程直接訪問同一塊內存區域,從而實現高效的數據交換。共享內存由內核管理,每個進程可以將共享內存段映射到自身的地址空間。
1.2 使用方法
創建和附加共享內存
創建或獲取一個共享內存段:
#include <sys/ipc.h>
#include <sys/shm.h>int shm_id = shmget(key_t key, size_t size, int shmflg);
附加共享內存段到進程的地址空間:
void *shmaddr = shmat(int shm_id, const void *shmaddr, int shmflg);
數據讀寫
共享內存的讀寫操作直接通過指針進行,如同普通內存操作。
分離和刪除共享內存
分離共享內存段:
int shmdt(const void *shmaddr);
刪除共享內存段:
int shmctl(int shm_id, IPC_RMID, NULL);
1.3 示例代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main() {key_t key = ftok("shmfile", 65);int shm_id = shmget(key, 1024, 0666|IPC_CREAT);char *str = (char*) shmat(shm_id, (void*)0, 0);printf("寫入數據到共享內存\n");strcpy(str, "Hello, World!");printf("數據: %s\n", str);shmdt(str);shmctl(shm_id, IPC_RMID, NULL);return 0;
}
?
二、消息隊列
2.1 概念
消息隊列(Message Queue)是一種以消息為單位的進程間通信機制,允許一個或多個進程以有序的方式發送和接收消息。消息隊列在內核中維護,進程通過消息隊列標識符進行操作。
2.2 使用方法
創建和獲取消息隊列
創建或獲取一個消息隊列:
#include <sys/ipc.h>
#include <sys/msg.h>int msg_id = msgget(key_t key, int msgflg);
?
發送消息
int msgsnd(int msg_id, const void *msgp, size_t msgsz, int msgflg);
?
接收消息
ssize_t msgrcv(int msg_id, void *msgp, size_t msgsz, long msgtyp, int msgflg);
?
刪除消息隊列
int msgctl(int msg_id, IPC_RMID, NULL);
?
2.3 示例代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>struct msg_buffer {long msg_type;char msg_text[100];
};int main() {key_t key = ftok("msgfile", 65);int msg_id = msgget(key, 0666 | IPC_CREAT);struct msg_buffer message;message.msg_type = 1;strcpy(message.msg_text, "Hello, World!");msgsnd(msg_id, &message, sizeof(message), 0);printf("消息發送: %s\n", message.msg_text);msgrcv(msg_id, &message, sizeof(message), 1, 0);printf("消息接收: %s\n", message.msg_text);msgctl(msg_id, IPC_RMID, NULL);return 0;
}
?
三、信號量
3.1 概念
信號量(Semaphore)是一種用于同步進程操作的機制,可以控制多個進程對共享資源的訪問。信號量可以是單個信號量(用于簡單的互斥)或信號量集合(用于復雜的同步)。
3.2 使用方法
創建和獲取信號量
創建或獲取一個信號量集:
#include <sys/ipc.h>
#include <sys/sem.h>int sem_id = semget(key_t key, int num_sems, int semflg);
?
初始化信號量
int semctl(int sem_id, int semnum, SETVAL, union semun arg);
?
操作信號量
信號量操作包括P操作(等待)和V操作(信號),通常使用?semop
函數進行操作。
struct sembuf {unsigned short sem_num;short sem_op;short sem_flg;
};int semop(int sem_id, struct sembuf *sops, size_t nsops);
?
3.3 示例代碼
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>union semun {int val;struct semid_ds *buf;unsigned short *array;
};void sem_wait(int sem_id) {struct sembuf sem_op;sem_op.sem_num = 0;sem_op.sem_op = -1;sem_op.sem_flg = 0;semop(sem_id, &sem_op, 1);
}void sem_signal(int sem_id) {struct sembuf sem_op;sem_op.sem_num = 0;sem_op.sem_op = 1;sem_op.sem_flg = 0;semop(sem_id, &sem_op, 1);
}int main() {key_t key = ftok("semfile", 65);int sem_id = semget(key, 1, 0666 | IPC_CREAT);union semun sem_union;sem_union.val = 1;semctl(sem_id, 0, SETVAL, sem_union);if (fork() == 0) {sem_wait(sem_id);printf("子進程正在使用共享資源\n");sleep(2);printf("子進程釋放共享資源\n");sem_signal(sem_id);} else {sem_wait(sem_id);printf("父進程正在使用共享資源\n");sleep(2);printf("父進程釋放共享資源\n");sem_signal(sem_id);}semctl(sem_id, 0, IPC_RMID, sem_union);return 0;
}