マルチプロセスデュアルbuffer読み取りと処理
4101 ワード
テーマの要件
Linuxプラットフォームの下の2つのC言語プログラムを編纂して以下の機能を実現する:(1)X、Yの2つのプロセスは互いに協力して入力ファイルの中のデータの処理を実現して、そして処理結果を出力ファイルに書き込む.(2)Xプロセスは,ブロックを読み取って入力ファイルを取り,入力データを共有メモリでYプロセスに転送する.(3)Yプロセスは、読み込んだデータ(テキストデータと仮定)をすべて大文字に処理し、出力ファイルに書き込む.(4)並列効率を向上させるために,X,Yの2つのプロセス間に2つの共有メモリ領域A,Bを作成する.XはデータをA領域に読み込み、Linuxの信号または信号量メカニズムでYプロセスに処理を通知する.YがA領域のデータを処理するとき、Xは引き続きB領域にデータを読み込む.Bゾーンデータが満たされた後、XプロセスはYプロセスに処理を通知し、自分でAゾーンにデータを読み込み続ける.このようにして、すべてのデータ処理が完了するまでループします.
問題を解く
Linuxプラットフォームの下の2つのC言語プログラムを編纂して以下の機能を実現する:(1)X、Yの2つのプロセスは互いに協力して入力ファイルの中のデータの処理を実現して、そして処理結果を出力ファイルに書き込む.(2)Xプロセスは,ブロックを読み取って入力ファイルを取り,入力データを共有メモリでYプロセスに転送する.(3)Yプロセスは、読み込んだデータ(テキストデータと仮定)をすべて大文字に処理し、出力ファイルに書き込む.(4)並列効率を向上させるために,X,Yの2つのプロセス間に2つの共有メモリ領域A,Bを作成する.XはデータをA領域に読み込み、Linuxの信号または信号量メカニズムでYプロセスに処理を通知する.YがA領域のデータを処理するとき、Xは引き続きB領域にデータを読み込む.Bゾーンデータが満たされた後、XプロセスはYプロセスに処理を通知し、自分でAゾーンにデータを読み込み続ける.このようにして、すべてのデータ処理が完了するまでループします.
問題を解く
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
", 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
");
}
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
");
return 0;
}