1

私は1週間前にセマフォと共有メモリの理解と操作を開始し、実際にこのプログラムを作成しました。問題は、何時間も見ていて、何も問題がないことです。コードがコンパイルされ、作成できます。ビルドしますが、実行しても何も起こりません...

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h> 
#include <sys/shm.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <semaphore.h>

#define MAXCHILDS 4
#define MAX_SIZE 10
#define MAX_WRITES 4

typedef struct{
    int m[MAX_SIZE][MAX_SIZE];
} matrix;

/*fork variables*/
pid_t child[MAXCHILDS];
/*semphores variables */
sem_t *empty, *full, * mutex;
/*share memory id*/
int shmid;
/*shared memory array pointer */
matrix * sh_mem;
/*pointer to matrix*/
int **p;


void init(){
      /*create pointer to matrix*/
      p = &sh_mem->m;
     /*semaphores unlink and creation */    
     sem_unlink("EMPTY");
     empty=sem_open("EMPTY",O_CREAT|O_EXCL,0700,MAX_WRITES);
     sem_unlink("FULL");
     full=sem_open("FULL",O_CREAT|O_EXCL,0700,0);
     sem_unlink("MUTEX");
     mutex=sem_open("MUTEX",O_CREAT|O_EXCL,0700,1);
    /*initialize shared memory */
    shmid = shmget(IPC_PRIVATE,sizeof(matrix),IPC_CREAT|0777);
    /*map shared memory*/
    sh_mem = (matrix*)shmat(shmid,NULL,0);
    if(sh_mem== (matrix*)(-1)){
        perror("shmat");
    }
}
void writer(int ** m){
    int i,k;
    for(i = 0;i<MAX_SIZE;i++){
        for(k= 0;k<MAX_SIZE;k++){
            m[i][k] = 0;
        }
    }

}
void reader(int **m){
    int i = 0;
    int k = 0;
    for(i = 0;i<MAX_SIZE;i++){
        for(k= 0;k<MAX_SIZE;k++){
            printf(m[i][k]);
        }
        printf("\n");
    }

}

void terminate() {
  sem_close(empty);
  sem_close(full);
  sem_close(mutex);
  sem_unlink("EMPTY");
  sem_unlink("FULL");
  sem_unlink("MUTEX");
  shmctl(shmid, IPC_RMID, NULL);
}

int main(int argc, char **argv)
{
    int i;
    init();

    for(i = 0;i<MAXCHILDS;i++){
        if((child[i]= fork()) < 0) // error occured
        {
            perror("Fork Failed");
            exit(1);
        }
        if((child[i] =fork())==0){
            writer(p);
            exit(0);
        }
    }
    /*father*/  
    reader(p);
    wait(NULL);

    terminate();


    return 0;
}

子は共有メモリにマトリックスを書き込むことになっており、父親は共有メモリ配列を読み取ってマトリックスを印刷することになっています。これを手伝ってくれませんか。助けてくれてありがとう ...

4

1 に答える 1

2

コードにいくつか問題があります。

  • p変数を次のように宣言します。

    int **p;
    

    ただし、配列の実際のタイプはですint[MAXSIZE][MAXSIZE]。これらは両方とも2次元配列と見なすことができますが、まったく同じタイプではなく、メモリ内で同じ構造を共有していません。

    • int **整数へのポインタへのポインタです。2次元配列として使用する場合は、2レベルの配列を表します。最初のレベル(ポインターを1回逆参照)には、int *それぞれが整数の1次元配列を指すポインターの配列が含まれています。
    • int[MAXSIZE][MAXSIZE]フラットな2次元配列です。MAXSIZE*MAXSIZEこれは、整数の配列への単一のポインターです。int[MAXSIZE*MAXSIZE]2レベルの添え字を使用できるという便利さを備えていますが、1次元配列と同じメモリ構造を備えています。

    Cでスタイル配列へのポインタを渡すことtype[][]は直感的ではなく、正しく理解するのは非常に困難です。私はそれをすることをお勧めしません。matrix代わりに、自分の型へのポインタを渡すことを検討してください。それでも、この宣言で機能させることは可能です。

    typedef int array2d[MAX_SIZE][MAX_SIZE];
    array2d *p;
    

    次に、mパラメータをinreaderwritertoに変更するか、array2d *mまたはの代わりにint **mとして使用する必要があります。これは醜くなります。私が言ったように、代わりにあなたのタイプを使用することを検討してください。*mmmatrix

    この問題はコンパイラーによって捕らえられるべきでした。それはあなたにたくさんのタイプの不一致の警告を与えるはずでした。常にでコンパイルしgcc -Wall、エラーや警告なしでプログラムをコンパイルすることを目指してください。

  • init()、設定pが早すぎます。sh_mem関数の開始時ではなく、割り当てられた後の関数の最後に設定する必要があります。

  • 上記のコメントで説明したように、関数で使用fork()しているプロセスが多すぎます。おそらく、ループを通過するたびに2回ではなく、1回だけmain()呼び出すことを意図していました。fork()for

  • ライターが共有メモリ構造への入力を完了するまで待たずに、先に進んでその内容を読み取ります。

    wait(NULL)への呼び出しの前にを移動したとしても、reader()それだけでは不十分であることに注意してくださいwait(NULL)。すべてではなく、1つの子プロセスが完了するのを待つだけだからです。

一般に、警告を有効にしてプログラムをコンパイルし、警告に注意を払い、プログラムに何が問題があるのか​​疑問に思う前に修正​​する必要があります。それでも予期しないことが発生する場合は、デバッガーで実行し、ブレークポイントを使用して変数を検査し、何が起こっているかを確認する必要があります。これらの2つの手法を使用すると、ここに投稿しなくても問題を解決できたはずです。

于 2012-11-05T01:59:17.780 に答える