2

私の最後の質問(複数の子プロセス)を参照して、私は現在、複数の子プロセスを使用して外部ソーティングの実装を作成しようとしています。

...
fp = fopen(pathname, "r"); // open inputfile in r mode
fgets(trash, 10, fp); // ignore first line

for (i=0; i<numberOfProcess; ++i) {
    #ifdef DBG
        fprintf(stderr, "\nDBG: Calling fork()\n"); 
    #endif

    if ((pids[i] = fork()) < 0) {
        perror("fork error");
        exit(EXIT_FAILURE);

    } else if (pids[i] == 0) { // Child Code

        if (numbersToSort % numberOfProcess == 0) { // 16 % 4 = 0
            partialDataSize = numbersToSort / numberOfProcess;          

            for (j=0; j<partialDataSize; j++) { 
                fscanf(fp, "%d", &arrayPartialData[j]);
                qsort(arrayPartialData, partialDataSize, sizeof(int), (void *)comp_num);

                //printf("%d\n", arrayPartialData[j]);
                // TODO: qsort data until partialDataSize
            }

        } 
        printf("pid: %d child process %d outputs: ", getpid(), pids[i]);
        printArray(arrayPartialData, partialDataSize);
        //break;
        exit(0);
    }  
}   

/* Wait for children to exit. */

while (numberOfProcess > 0) {
    pid = wait(&status);
    --numberOfProcess;
}

fclose(fp);

しかしもちろん、このコードはfscanfのために、入力ファイルから同じシーケンスのソートされた整数を出力します。たとえば、入力ファイルの先頭に5 1 4が含まれている場合、次のように出力されます。

(1番目の子)1 4 5
(2番目の子)1 4 5

(2つの子プロセスを使用)。fscanfは入力ストリームの先頭から整数の読み取りを開始するため。

今の私の問題は、前の子プロセスが残った時点からどのように数字を読み続けることができるかということです。たとえば、入力ファイルに5 1 4 8 5 10が含まれている場合、次のように出力できます。

(最初の子供)1 4 5

(2番目の子供)5 8 10

前もって感謝します;)

4

4 に答える 4

1

同等のストリームではなく、下位レベルの open() および read() を使用します。そうしないと、stdio バッファーと基になるファイル記述子の同期について心配する必要があります。完全な数値を読み取るにはまだ問題があることに注意してください。そのため、おそらくプロセス間の同期が必要になるでしょう。

別の方法として、単一のプロセスでファイルを読み取り、(pipe() を使用して) 並べ替えを行うサブプロセスに行のサブセットを書き込み、それをマージを行う別のプロセスに書き込むことをお勧めします。

于 2009-05-18T16:23:37.467 に答える
0

fscanf を使用している場合、できることは、各プロセスに番号を読み取らせ、処理すべき番号に到達するまで番号を破棄させることだけです。あなたの場合、 i*partialdatasize の数値を破棄してください。

たとえば、5 7 3 1 4 8 5 10 2 は 5 7 3 になる可能性があります。

1 4 8

5 10 2

どちらを与えるか

3 5 7

1 4 8

2 5 10.

次に、ソートされた結果をマージする方法を考え出す必要があります。

于 2009-05-18T16:20:39.330 に答える
0

整数をバイナリとして保存できる場合。最初のスレッドにそのブロックを読み取らせることができます

fread(&arrayPartialData[j], sizeof(int), partialDataSize, fp);

2番目のスレッドよりも、すでに読み取られたブロックをスキップできます(各ブロックのサイズがわかっているため)。その後、データを破棄することなく、そこから読み取りを開始できます。

fseek(partialDataSize * threadNumber);

また、フォークは非常にコストがかかるため、スレッドを使用することをお勧めします。スレッドのチュートリアル

于 2009-05-18T16:34:17.493 に答える