本文關鍵字: 內存共享
1.實驗目的
通過編寫共享內存實驗,進一步了解使用共享內存的具體步驟,同時加深對共享內存的理解。在本實驗中,采用信號量作為同步機制完善兩個進程(“生產者”和“消費者”)之間的通信,其功能類似于4.6節中的實例。在實例中使用信號量同步機制。
2.實驗內容
該實現要求利用共享內存實現文件的打開和讀寫操作。
3.實驗步驟
(1)畫出流程圖。該實驗流程圖如圖1所示。
 圖1 實驗流程圖
(2)編寫代碼。下面是共享內存緩沖區的數據結構的定義:
/* shm_com.h */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_BUFF_SZ 2048
struct shm_buff
{
int pid;
char buffer[SHM_BUFF_SZ];
};
以下是“生產者”程序部分:
/* sem_com.h 和 sem_com.c 與4.4節示例中的同名程序相同 */
/* producer.c */
#include "shm_com.h"
#include "sem_com.h"
#include <signal.h>
int ignore_signal(void)
{ /* 忽略一些信號,以免非法退出程序 */
signal(SIGINT, SIG_IGN);
signal(SIGSTOP, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
return 0;
}
int main()
{
void *shared_memory = NULL;
struct shm_buff *shm_buff_inst;
char buffer[BUFSIZ];
int shmid, semid;
/* 定義信號量,用于實現訪問共享內存的進程間的互斥 */
ignore_signal(); /* 防止程序非正常退出 */
semid = semget(ftok(".", 'a'), 1, 0666|IPC_CREAT); /* 創建一個信號量 */
init_sem(semid);/* 初始值為1 */
/* 創建共享內存 */
shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
if (shmid == -1)
{
perror("shmget failed");
del_sem(semid);
exit(1);
}
/* 將共享內存地址映射到當前進程地址空間 */
shared_memory = shmat(shmid, (void*)0, 0);
if (shared_memory == (void*)-1)
{
perror("shmat");
del_sem(semid);
exit(1);
}
printf("Memory attached at %X\n", (int)shared_memory);
/* 獲得共享內存的映射地址 */
shm_buff_inst = (struct shared_use_st *)shared_memory;
do
{
sem_p(semid);
printf("Enter some text to the shared memory(enter 'quit' to exit):");
/* 向共享內存寫入數據 */
if (fgets(shm_buff_inst->buffer, SHM_BUFF_SZ, stdin) == NULL)
{
perror("fgets");
sem_v(semid);
break;
}
shm_buff_inst->pid = getpid();
sem_v(semid);
} while(strncmp(shm_buff_inst->buffer, "quit", 4) != 0);
/* 刪除信號量 */
del_sem(semid);
/* 刪除共享內存到當前進程地址空間中的映射 */
if (shmdt(shared_memory) == 1)
{
perror("shmdt");
exit(1);
}
exit(0);
}
以下是“消費者”程序部分:
/* customer.c */
#include "shm_com.h"
#include "sem_com.h"
int main()
{
void *shared_memory = NULL;
struct shm_buff *shm_buff_inst;
int shmid, semid;
/* 獲得信號量 */
semid = semget(ftok(".", 'a'), 1, 0666);
if (semid == -1)
{
perror("Producer is'nt exist");
exit(1);
}
/* 獲得共享內存 */
shmid = shmget(ftok(".", 'b'), sizeof(struct shm_buff), 0666|IPC_CREAT);
if (shmid == -1)
{
perror("shmget");
exit(1);
}
/* 將共享內存地址映射到當前進程地址空間 */
shared_memory = shmat(shmid, (void*)0, 0);
if (shared_memory == (void*)-1)
{
perror("shmat");
exit(1);
}
printf("Memory attached at %X\n", (int)shared_memory);
/* 獲得共享內存的映射地址 */
shm_buff_inst = (struct shm_buff *)shared_memory;
do
{
sem_p(semid); printf("Shared memory was written by process %d :%s",
shm_buff_inst->pid, shm_buff_inst->buffer);
if (strncmp(shm_buff_inst->buffer, "quit", 4) == 0)
{
break;
}
shm_buff_inst->pid = 0;
memset(shm_buff_inst->buffer, 0, SHM_BUFF_SZ);
sem_v(semid);
} while(1);
/* 刪除共享內存到當前進程地址空間中的映射 */
if (shmdt(shared_memory) == -1)
{
perror("shmdt");
exit(1);
}
/* 刪除共享內存 */
if (shmctl(shmid, IPC_RMID, NULL) == -1)
{
perror("shmctl(IPC_RMID)");
exit(1);
}
exit(0);
}
4.實驗結果
實驗運行結果如下:
$./producer
Memory attached at B7F90000
Enter some text to the shared memory(enter 'quit' to exit):First message
Enter some text to the shared memory(enter 'quit' to exit):Second message
Enter some text to the shared memory(enter 'quit' to exit):quit
$./customer
Memory attached at B7FAF000
Shared memory was written by process 3815 :First message
Shared memory was written by process 3815 :Second message
Shared memory was written by process 3815 :quit
本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》
熱點鏈接:
1、linux 共享內存
2、linux有名管道通信實驗
3、linux 消息隊列
4、linux下的信號量
5、linux下的信號處理實例
更多新聞>> |