編寫Linux平臺下的兩個C語言程序實現以下功能:
(1)X、Y兩個進程相互配合實現對輸入文件中數據的處理,並將處理結果寫入輸出文件。
(2)X進程負責讀分塊取輸入文件,並將輸入數據利用共享內存傳輸給Y進程。
(3)Y進程負責將讀入的數據(假定皆爲文本數據)所有處理成大寫,而後寫入輸出文件。
(4)爲提升並行效率,X、Y兩個進程之間建立2個共享內存區A、B。X讀入數據到A區,而後用Linux的信號或信號量機制通知Y進程進行處理;在Y處理A區數據時,X繼續讀入數據到B區;B區數據被填滿以後,X進程通知Y進程處理,本身再繼續向A區讀入數據。如此循環直至所有數據處理完畢。post
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <ctype.h> #include <semaphore.h> #include <sys/ipc.h> #include <sys/shm.h> const int BUFFER_SIZE = 2048; int main(int argc, char const *argv[]) { argv[1]; // 文件 int inputFile, outputFile; inputFile = open(argv[1], O_RDONLY); if(inputFile <= 0 ){ printf("no file %s \n", argv[1]); return 0; } outputFile = open("./output.txt", O_WRONLY | O_CREAT, 0666); // 信號量 sem_t *sem1; sem_t *sem2; sem1 = sem_open("sem1", O_CREAT, 0666, 1); sem2 = sem_open("sem2", O_CREAT, 0666, 0); // 共享內存 // 定義交換空間結構體 struct switchBuffer { char buffer[BUFFER_SIZE]; int flag; }; struct switchBuffer *buffera; // 交換空間a,b struct switchBuffer *bufferb; int shmaId, shmbId; // 建立共享內存 shmaId = shmget((key_t)11, sizeof(buffera), 0666 | IPC_CREAT); shmbId = shmget((key_t)22, sizeof(bufferb), 0666 | IPC_CREAT); // 主進程讀取數據 // 子進程處理後寫入數據 pid_t cpid; cpid = fork(); if (cpid < 0) { printf("error in fork\n"); } else if (cpid == 0) { // 子進程 printf("child process pid: %d \t", getpid()); // 共享內存映射到進程空間 buffera = (struct switchBuffer *)shmat(shmaId, 0, 0); bufferb = (struct switchBuffer *)shmat(shmbId, 0, 0); int switchFlag = 1; while(1) { sem_wait(sem2); if (switchFlag) { for (int i = 0; i < buffera->flag; ++i) { buffera->buffer[i] = toupper(buffera->buffer[i]); } write(outputFile, buffera->buffer, buffera->flag); } else { for (int i = 0; i < bufferb->flag; ++i) { bufferb->buffer[i] = toupper(bufferb->buffer[i]); } write(outputFile, bufferb->buffer, bufferb->flag); } switchFlag = !switchFlag; sem_post(sem1); } } else { // 主進程 // 共享內存映射到進程空間 buffera = (struct switchBuffer *)shmat(shmaId, 0, 0); bufferb = (struct switchBuffer *)shmat(shmbId, 0, 0); int fileFlag = 0; int switchFlag = 1; // 1.讀取文件->buffer a // 2.等待處理進程 // 3.觸發處理進程 // 4.讀取文件->buffer b // 5.等待處理進程 // 6.觸發處理進程 // 開始時預先觸發2,開始運行任務 // 經過read文件爲0判斷終止條件 // 終止後再次等待處理線程處理最後的一個buffer while (1) { if (switchFlag) { fileFlag = read(inputFile, buffera->buffer, BUFFER_SIZE); buffera->flag = fileFlag; } else { fileFlag = read(inputFile, bufferb->buffer, BUFFER_SIZE); bufferb->flag = fileFlag; } switchFlag = !switchFlag; if (fileFlag <= 0) break; sem_wait(sem1); sem_post(sem2); } sem_wait(sem1); } // destory close(inputFile); close(outputFile); sem_close(sem1); sem_close(sem2); sem_unlink("sem1"); sem_unlink("sem2"); shmdt(buffera); shmdt(bufferb); shmctl(shmaId, IPC_RMID, 0); shmctl(shmbId, IPC_RMID, 0); printf("over\n"); return 0; }