Я пробираюсь через книгу по C ++ и операционным системам, и я наткнулся на задание, которое требует создания, записи и чтения из каналов. Однако моя программа зависает при чтении из второго канала. Моя программа заключается в приеме ввода и разборе строки с пробелом в токены и соответствующей классификации этих токенов. Мой код ниже с моей проблемной зоной. Любая помощь, как всегда, очень ценится.
edit: Предполагается, что у него двое детей. Один для обработки маркеров с разделителями, а другой для определения типа маркеров с разделителями. Что касается отладки, у меня есть доступ только к cout как к отладчику. Поэтому я вставил cout перед чтением и после того, как появилось чтение, но после не сделал.
#include <iostream>
#include <fstream>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;
//declaring the pipes
int pipeOne[2];
int pipeTwo[2];
struct inputStruct {
char str[256]; /* one extra spot for \n */
int len; /* length of str */
int flag; /* 0 for normal input, 1 to indicate “done” */
};
struct tokenStruct {
char token[256]; /* tokens can be 255 max */
int flag; /* same as inputStruct */
int tokenType; /* a code value */
};
void dataProcess(){
//new input struct to contain the the input from the parent
inputStruct input;
//the intial read from the pipe to populate the input stuct
read( pipeOne[0], (char*)&input, sizeof(inputStruct));
//set the flag
int flag = input.flag;
while (flag != 1){
int size = 0;
//get the size of the array up until the null character
while (input.str[size] != '\0'){
size++;
}
//Here's the parsing of each token
for (int i=0; i<size; i++) {
int tokenLength;
tokenStruct token;
//while the char isn't white space or null increment through it
while (input.str[i] != ' ' && input.str[i] != '\0') {
//a is the index of the string token
int a = 0;
//write the parsed string
token.token[a] = input.str[i];
a++;
i++;
}
//write to process 2
write(pipeTwo[1], (char*)&token, sizeof(tokenStruct));
}
//read again and store the results
read(pipeOne[0], (char*)&input, sizeof(inputStruct));
flag = input.flag;
}
tokenStruct token;
token.flag = flag;
//final write to the second child to tell it to commit suicide
write(pipeTwo[1], (char*)&token, sizeof(tokenStruct));
exit(0);
}
void tokenClassifer(){
tokenStruct token;
//Problem area is here on ****************************************************
//the initial read
read(pipeTwo[0], (char*)&token, sizeof(tokenStruct));
while (token.flag != 1){
int size = 0;
//get the size of the array up until the null character
while (token.token[size] != '\0'){
size++;
}
if (size == 1) {
//check for the one char things first
switch (token.token[0])
{
case '(':
token.tokenType = 0;
break;
case ')':
token.tokenType = 0;
break;
case ';':
token.tokenType = 0;
break;
case '+':
token.tokenType = 1;
break;
case '-':
token.tokenType = 1;
break;
case '/':
token.tokenType = 1;
break;
case '*':
token.tokenType = 1;
break;
default:
if (isdigit(token.token[0])) {
token.tokenType = 2;
} else {
token.tokenType = 3;
}
break;
}
} else {
bool isStr;
int i = 0;
//check for the more than one character
while (token.token[i] != '\0'){
//check if it's a string or digits
if (isdigit(token.token[0])) {
isStr=false;
} else{
//set up the bools to show it is a string
isStr=true;
break;
}
}
//if it is a string token type 3
if (isStr) {
token.tokenType = 3;
} else {
//if not then it's digits and token type 2
token.tokenType = 2;
}
}
//print out the token and token type
cout << "Token type is: " << token.tokenType << "Token value is: " << token.token << "\n";
//read the pipe again and start the process all over
read(pipeTwo[0], (char*)&token, sizeof(tokenStruct));
}
exit(0);
}
int main()
{
//create the pipes for reading and writing between processes
pipe(pipeOne);
pipe(pipeTwo);
//fork off both processes
int value = fork();
int value2 = fork();
//do the process for the first fork
if(value == 0){
//fork one
dataProcess();
} else {
wait(0);
}
//do the process for the second fork
if (value2 == 0) {
//fork two
//the token classifer function for the second fork
tokenClassifer();
} else {
cout << "Type some tokens (or just press enter to quit) \n";
//this is all of the parent functions
for (string line; getline(cin, line); )
{
inputStruct input;
if (line.empty())
{
// if the line is empty, that means the user didn't
// press anything before hitting the enter key
input.flag = 1;
write( pipeOne[1], (char*)&input, sizeof(inputStruct));
break;
} else {
//else copy the string into an array
strcpy(input.str, line.c_str());
//set the flag to zero to show everthing is ok
input.flag = 0;
}
//write the stuct to the pipe
write( pipeOne[1], (char*)&input, sizeof(inputStruct));
cout << "Type some tokens (or just press enter to quit) \n";
}
wait(0);
}
}