生產(chǎn)者與消費者模式 適用場景
生產(chǎn)者和消費者模式適用于生產(chǎn)者和消費者之間存在數(shù)據(jù)交換的場景。在這種模式中,生產(chǎn)者負(fù)責(zé)生產(chǎn)數(shù)據(jù)并將其放入緩沖區(qū),而消費者負(fù)責(zé)從緩沖區(qū)中取出數(shù)據(jù)并進行處理。這種模式的優(yōu)點是可以實現(xiàn)生產(chǎn)者和消費者之間的解耦,使得它們可以獨立地進行操作,從而提高了系統(tǒng)的并發(fā)性和可擴展性。
生產(chǎn)者和消費者模式適用于許多場景,例如:
- 操作系統(tǒng)中的進程和線程之間的通信;
- 數(shù)據(jù)庫系統(tǒng)中的讀寫操作;
- 網(wǎng)絡(luò)通信中的數(shù)據(jù)傳輸;
- 多線程編程中的任務(wù)隊列等。
總之,只要存在生產(chǎn)者和消費者之間的數(shù)據(jù)交換,就可以考慮使用生產(chǎn)者和消費者模式來實現(xiàn)。文章來源:http://www.zghlxwxcb.cn/news/detail-435618.html
代碼實例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
#define SHM_KEY 1234
int main() {
int shmid;
int *shmaddr;
int in = 0, out = 0;
sem_t *empty, *full, *mutex;
// 創(chuàng)建共享內(nèi)存
shmid = shmget(SHM_KEY, BUFFER_SIZE * sizeof(int), IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
exit(1);
}
// 將共享內(nèi)存附加到進程的地址空間
shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (int *) -1) {
perror("shmat");
exit(1);
}
// 初始化信號量
empty = sem_open("empty", O_CREAT, 0666, BUFFER_SIZE);
full = sem_open("full", O_CREAT, 0666, 0);
mutex = sem_open("mutex", O_CREAT, 0666, 1);
if (empty == SEM_FAILED || full == SEM_FAILED || mutex == SEM_FAILED) {
perror("sem_open");
exit(1);
}
// 生產(chǎn)者進程
if (fork() == 0) {
int item;
while (1) {
item = rand() % 100; // 生產(chǎn)一個隨機數(shù)
sem_wait(empty); // 等待緩沖區(qū)非滿
sem_wait(mutex); // 互斥訪問緩沖區(qū)
shmaddr[in] = item; // 將 item 放入共享內(nèi)存
in = (in + 1) % BUFFER_SIZE;
printf("Producer produced item %d\n", item);
sem_post(mutex); // 釋放緩沖區(qū)
sem_post(full); // 增加緩沖區(qū)中的項目數(shù)
}
}
// 消費者進程
if (fork() == 0) {
int item;
while (1) {
sem_wait(full); // 等待緩沖區(qū)非空
sem_wait(mutex); // 互斥訪問緩沖區(qū)
item = shmaddr[out]; // 從共享內(nèi)存中取出一個項目
out = (out + 1) % BUFFER_SIZE;
printf("Consumer consumed item %d\n", item);
sem_post(mutex); // 釋放緩沖區(qū)
sem_post(empty); // 增加緩沖區(qū)中的空閑位置數(shù)
}
}
// 等待子進程結(jié)束
wait(NULL);
wait(NULL);
// 刪除共享內(nèi)存和信號量
shmdt(shmaddr);
shmctl(shmid, IPC_RMID, NULL);
sem_unlink("empty");
sem_unlink("full");
sem_unlink("mutex");
return 0;
}
在該示例中,我們使用了共享內(nèi)存和信號量來實現(xiàn)生產(chǎn)者和消費者模式。首先,我們使用 shmget()
函數(shù)創(chuàng)建共享內(nèi)存,然后使用 shmat()
函數(shù)將共享內(nèi)存附加到進程的地址空間中。接著,我們使用 sem_open()
函數(shù)初始化信號量。在生產(chǎn)者進程中,當(dāng)共享內(nèi)存非滿時,生產(chǎn)者將 item 放入共享內(nèi)存,并增加 full 信號量的值;在消費者進程中,當(dāng)共享內(nèi)存非空時,消費者從共享內(nèi)存中取出一個項目,并增加 empty 信號量的值。由于信號量的特性,當(dāng)信號量的值為 0 時,調(diào)用 sem_wait()
函數(shù)的進程將被阻塞,直到信號量的值大于 0。因此,我們不需要使用 while 循環(huán)來輪詢共享內(nèi)存的狀態(tài)。最后,我們使用 shmdt()
函數(shù)將共享內(nèi)存從進程的地址空間中分離,并使用 shmctl()
函數(shù)刪除共享內(nèi)存。同時,我們使用 sem_unlink()
函數(shù)刪除信號量。文章來源地址http://www.zghlxwxcb.cn/news/detail-435618.html
到了這里,關(guān)于【設(shè)計模式】C語言使用共享內(nèi)存和信號量,完美實現(xiàn)生產(chǎn)者與消費者模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!