Нужна консультация fork, pipe, execvp
От: Saddam Россия http://saddam.narod.ru
Дата: 13.03.17 15:45
Оценка:
Коллеги, добрый вечер!
Изучаю многопоточное программирование в линуксе. Пробую написать аналог пайпа.
Код ниже. Никак не получается запустить больше двух процессов. Мастер зависает наглухо.
Туплю... Весь день не могу победить проблему. Ткните носом, буду очень признателен....

#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <vector>
#include <array>
//#include <algorithm>
//#include <functional>
//#include <cctype>
//#include <locale>
#include <string.h>
#include <sys/wait.h>

using namespace std;

void parce(char *s, char delim, std::vector<char *> &CmdList)
{
    unsigned int l=strlen(s);
    unsigned int i=0;
    CmdList.push_back(s);
    //while (s[strlen(s)-1]==' ') s[strlen(s)-1]=0;
    for (i=0;i<l;i++)
        if (s[i]==delim)
        {
            s[i]=0;
            i++;
            while (s[i]==' ') {s[i]=0;i++;}
            if (strlen(&s[i])) CmdList.push_back(&s[i]);
            while (s[strlen(&s[i])-1]==' ') s[strlen(&s[i])-1]=0;
    }
}
int main() {
    std::filebuf fb;
    fb.open ("/home/saddam/Pipe.log",std::ios::out);
    std::ostream os(&fb);
    std::vector<char *> CmdList;
    char cmdLine[1024];
    int iChildPID=0, subCount=0;
    //cin>>cmdLine;
    strcpy(cmdLine,"who | sort | uniq -c | sort -nk1");
    //strcpy(cmdLine,"who | sort -nk1");
    parce(cmdLine,'|',CmdList);
    std::vector<int *> Pipes;
    for (unsigned int i=0;i<CmdList.size()-1;i++)
    {
        int *Pipe=new int[2];
        Pipes.push_back(Pipe);
        if (0<pipe(Pipes[i]))
        {
            cout << "Pipe error" << endl;
            return errno;
        }
        os << "Pipe" << i <<": " << Pipes[i][0]<<", "<<Pipes[i][1]<<endl;
    }
    int fd = 0;
    while (!CmdList.empty())
    {
        std::vector<char *> ParamList;
        parce(CmdList.front(),' ',ParamList);
        ParamList.push_back(NULL);
        if (!(iChildPID=fork()))
        {
            if (CmdList.size()>1)
            {
                dup2(Pipes[subCount][1],1);//O_CLOEXEC
                close(Pipes[subCount][0]);
                Pipes[subCount][1]=1;
                os<<getpid()<<" Pipe(>)"<<subCount<<": "<< Pipes[subCount][0]<<", "<<Pipes[subCount][1]<<endl;
            }
            else
            {
                fd = open("/home/saddam/result.out",   O_CREAT | O_RDWR );
                dup2(fd,1);
                os<<getpid()<<" File(>)\n";
            }
            if (subCount)
            {
                dup2(Pipes[subCount-1][0],0);
                Pipes[subCount-1][0]=0;
                close(Pipes[subCount-1][1]);
                os<<getpid()<<" Pipe(<)"<<subCount-1<<": "<< Pipes[subCount-1][0]<<", "<<Pipes[subCount-1][1]<<endl;
            }
            if (-1==execvp(CmdList.front(),ParamList.data()))
                return errno;
        }
        subCount++;
        cout <<" PID:"<<iChildPID<<" Count:"<<subCount<< endl;
        CmdList.erase(CmdList.begin());
    }
    int status=0;
    cout <<"Waiting for "<<subCount<< endl;
    int pid ;
    for (int i=1;i<subCount;i++)
    {
        cout <<"Waiting for "<<subCount-i<< endl;
        pid=wait(&status);
        cout <<"PID: "<<pid<<" terminated \n";
    }
    close(fd);
    cout <<"Master is finished!"<< endl; // prints !!!Hello World!!!
    fb.close();
    return 0;
}
- Вы знаете — жаль, просто по-человечески жаль Памелу Андерсон, которая никогда не сможет сыграть на баяне...
fork pipe execvp linux
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.