0

この例のようなプログラムを実装しようとしています:

プログラムは4つのプロセス間で整数を渡し、各プロセスは整数を減らします

各プロセスには独自のメールボックスがあります

各プロセスは、変数「カウンター」のメールボックスをチェックし、見つかった場合はデクリメントします

次に、カウンター変数を次のプロセスに送信します

しかし、プログラムにバグがあり、見つけることができません。これは課題であり、バグを見つけるのに役立つヒントを探しているだけであることに注意してください。

ここに画像の説明を入力

typedef struct {
    int counter;
    char data[256];
    int id; //id of the process that previously decremented the counter
} msg;



int main(int arqc, char *argv[]){
    int key=9;
    int id=0;
    pid_t  pid;
    int num=5;
    int    i, k;
    int arr[5];


    //create 5 forks
    if (arqc !=  2){
        num=5;
    }else{
        int ret = sscanf(argv[1], "%d", &num);
        if (ret != 1)return 0;
    }
    for(i=0 ; i<num ; i++){
        if ((pid = fork()) == -1) {
            fprintf(stderr, "can't fork, error %d\n", errno);
            exit(EXIT_FAILURE);
        }
        if (pid == 0) {
            id=i;
        }
        else {
            break;
        }
    }



    //process 1 to n comes here
    msg m;
    int boxid = msgget(id, 0600 | IPC_CREAT);
    arr[id]=boxid;
    int firstRun=1;

    //initiate the first move
    if((id==0)&&(firstRun==1)){
        m.counter = INIT_COUNTER;

        //send msg to next process
        msgsnd(arr[id], &m, sizeof(msg), 0); //send msg to own inbox
        firstRun=0;
    }



    while(1){
        //check inbox of current process
        int rec = msgrcv(arr[id], &m, sizeof(msg), 0, 0);

        printf("Im %d, counter is %d, rec is %d\n",id, m.counter, rec);


        int index;
        if(id==num){
            index=0;
        }else{
            index=id+1;
        }

        //send message to the next inbox
        int sent = msgsnd(arr[index], &m, sizeof(m), 0);

        printf( "Error opening file: %s\n", strerror( errno ) );

        sleep(1);
    }

}
4

2 に答える 2

1

あなたのイニシャルmsgsndは無効な引数で失敗し、そこからすべてが変更されます。

SysV メッセージ キューでは、メッセージの最初のフィールドとしてメッセージ タイプ フィールドが必要なので、このようなことを行う必要があります。

typedef struct
{
    long int  mtype;
    int counter;
    char data[256];
    int id; //id of the process that previously decremented the counter
} msg;

また、メッセージを送信する前に、メッセージを何かに設定し、正しい長さを設定する必要があります。

//initiate the first move
if ((id == 0) && (firstRun == 1))
{
    m.mtype = 100;
    m.counter = INIT_COUNTER;
    strncpy(m.data, "some kind of message is nice", sizeof(m.data));
    m.id = id;

    size_t msgsize = sizeof(msg) - sizeof(long int);

    //send msg to next process
    int sent = msgsnd(arr[id], &m, msgsize, 0); //send msg to own inbox

    if (sent == -1)
    {
        perror("msgsend");
        exit(1);
    }

    firstRun = 0;
}

これを超える問題が発生します (たとえば、msgrcvs で正しいサイズを設定する) が、これで最初のこぶを乗り越えることができます。

于 2013-10-23T03:44:40.183 に答える
0

まず第一に、あなたの側で何の努力もせずに、SO クラウドがあなたのために (宿題?) 問題を解決することを期待するのは不合理です。問題が何である、プログラムが現在どのように動作しているか、デバッグのためにどのような手順が行われたかは不明です。

暴言はさておき、参加者を 2 人だけ残してすべての手順を省略し、単純な構成で機能させることをお勧めします。機能したら、別のものを追加し、引き続き機能することを確認します。

于 2013-10-23T02:14:52.343 に答える