1

コマンドラインから文字列を取得し、それを逆にして、fork()を使用して個別の子プロセスで各文字を出力するという割り当てがあります。fork()呼び出しから正しい出力が得られないだけです。問題は、インデックスが出力で乱雑になることです。たとえば、3、1、2、0のように、3、2、1,0などです。単語の長さは3文字ですが(常にではありません)、4文字以上の単語では通常正しくありません。ループは、fork()を呼び出さなくても正しく機能します。

これが私の主な機能であり、問​​題はforループ内に存在します。

int main(int argc, char **argv){
    pid_t childpid = 0;
    int i;
    char* invert = new char[strlen(argv[1])+1];
    int invert_length = strlen(argv[1]);
    strcpy(invert, argv[1]);
    for(i=invert_length-1; i>=0; i--){
        childpid = fork();
        if(childpid==(pid_t) 0){
            //I am the child            
            cout<<"Child ["<< i <<"] = "  << invert[i] <<"."<<endl;
            break;
        }
    }   
    return 0;
}
4

4 に答える 4

2

プログラムを変更するだけで機能します。子供に次のフォークをさせます。各プロセスは、生成されたプロセスを待機します。

int main(int argc, char **argv){
    pid_t childpid = 0;
    int i;
    char* invert = new char[strlen(argv[1])+1];
    int invert_length = strlen(argv[1]);
    strcpy(invert, argv[1]);
    for(i=invert_length-1; i>=0; i--){
        childpid = fork();
        if(childpid==(pid_t) 0){
            //I am the child
            cout<<"Child ["<< i <<"] = "  << invert[i] <<"."<<endl;
            continue;
        }
        break;
    }
    wait(0);
    return 0;
}

編集: Skizzは、各プロセスが次のプロセスを起動する前にその作業を実行することに反対しました。すべてのプロセスを最初に起動するという質問には要件はありませんでしたが、以下のバージョンではそれが行われます。

int main(int argc, char **argv){
    pid_t childpid = 0;
    int i;
    char* invert = new char[strlen(argv[1])+1];
    int invert_length = strlen(argv[1]);
    strcpy(invert, argv[1]);
    for(i=0; i<invert_length; ++i){
        childpid = fork();
        if(childpid!=(pid_t) 0){
            wait(0);
            break;
        }
    }
    if (i-->0) cout<<"Child ["<< i <<"] = "  << invert[i] <<"." <<endl;
    return 0;
}
于 2012-07-11T10:53:20.713 に答える
0

これは、pthreadの場合と同じ状況です。子がスポーン順に実行されるという保証はありません。マインドSIGCHLD。

于 2012-07-11T10:34:35.940 に答える
0

問題は、フォーク呼び出しが新しいプロセスを生成し、呼び出しプロセスを複製することです。ループ内でこれを行うと、すべて同時に実行したい多くのプロセスができます。実行される順序(CPUは一度に1つのプロセスしか実行できないため*)は、実行するプロセスを選択するOSに依存するため、出力は不確定になります。

この問題を解決するには、生成された各プロセスは、いつ出力するかを知る必要があります。これは、プロセス間で何らかの同期を使用することを意味します。

ノート:

  • 簡単にするために、ハイパースレッディング/マルチコアは無視しました。
于 2012-07-11T10:39:46.840 に答える
0

編集:

フォークしてから呼び出しwaitて、HW要件を満たすことができます。以下の私の最初の答えは、これをより複雑な環境(実際のアプリ)で実行する方法と、別のプロセスでコードを実行することを利用する方法です。

wait上記のように追加

int main(int argc, char **argv){
    pid_t childpid = 0;
    int i;
    char* invert = new char[strlen(argv[1])+1];
    int invert_length = strlen(argv[1]);
    strcpy(invert, argv[1]);
    for(i=invert_length-1; i>=0; i--){
        childpid = fork();
        if(childpid==(pid_t) 0){
            //I am the child            
            cout<<"Child ["<< i <<"] = "  << invert[i] <<"."<<endl;
            break;
        }
        else {
          int stat;
              wait(&stat);
        }
    }   
    return 0;
}

@illusionoflifeに同意しますが、宿題があれば可能でなければなりません

SIGCHLDのイベントハンドラー(たとえば、libeventを使用)をセットアップし、最初のSIGGCHLDを受信した後に次の子を起動できます。

この演習のポイントは、複数のCPU間での負荷分散ではなく、コピーオンライトで実行できることを示すことです。

これが私が数ヶ月前にあなたが始めるために尋ねた質問です

于 2012-07-11T10:40:28.793 に答える