简体   繁体   中英

C Linux pthreads: sending data from one thread to antoher using message queue gives unexpected result

I am writing a program that will transfer 50 integers from one thread to another using message queue and upon receiving the integers the receiver thread will print them.

At the moment the receiver thread prints first 13 integers(0,1,2..12) but after that it just prints all 0's.

Here is my code so far:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>


//define declarations
#define SIZE     50


//structs
typedef struct msgbuf {
         long    mtype;
         int    data[SIZE];
         } data_buf;


//function declarations
void *send_data();
void *receive_data();

main()
{
     pthread_t thread1;
     pthread_t thread2;
     int ret_val_t1;
     int ret_val_t2;

     //create thread1
     ret_val_t1 = pthread_create( &thread1, NULL, send_data, NULL);
     if(ret_val_t1)
     {
         fprintf(stderr,"Error - pthread_create() return value: %d\n",ret_val_t1);
         exit(EXIT_FAILURE);
     }

     //create thread2
     ret_val_t2 = pthread_create( &thread2, NULL, receive_data, NULL);
     if(ret_val_t2)
     {
         fprintf(stderr,"Error - pthread_create() return value: %d\n",ret_val_t2);
         exit(EXIT_FAILURE);
     }

     printf("pthread_create() for thread 1 returns: %d\n",ret_val_t1);
     printf("pthread_create() for thread 2 returns: %d\n",ret_val_t2);

     //wait untill threads are done with their routines before continuing with main thread
     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL); 

     exit(EXIT_SUCCESS);
}

void *send_data(){

    int msqid;
    int msgflg = IPC_CREAT | 0666;
    key_t key;
    data_buf sbuf;
    size_t buf_length;

    //get the message queue id for the key with value 1234
    key = 1234;

    (void) fprintf(stderr, "\nmsgget: Calling msgget(%#lx,\%#o)\n", key, msgflg);

    if ((msqid = msgget(key, msgflg )) < 0) {
        perror("msgget");
        exit(1);
    }
    else{ 
    (void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);
    }

    //send message type 1
    sbuf.mtype = 1;

    (void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);

    //fill the array that is to be sent from thread1 to thread2
    int i = 0;
    for(i = 0; i < SIZE; i++){
    sbuf.data[i] = i;
    }   

    (void) fprintf(stderr,"msgget: msgget succeeded: msqid = %d\n", msqid);

    buf_length = SIZE;

    //send data from thread1 to thread2
    if (msgsnd(msqid, &sbuf, buf_length, IPC_NOWAIT) < 0) {
        perror("msgsnd");
        exit(1);
    }

   else 
      printf("Data sent\n");
}

void *receive_data(){
    int msqid;
    key_t key;
    data_buf  rbuf;

    //get the message queue id for the key with value 1234
    key = 1234;

    if ((msqid = msgget(key, 0666)) < 0) {
        perror("msgget");
        exit(1);
    }

    //receive the answer with message type 1
    if (msgrcv(msqid, &rbuf, SIZE, 1, 0) < 0) {
        perror("msgrcv");
        exit(1);
    }


    //print received answer
    int j = 0;
    for(j = 0; j < SIZE; j++){
    printf("%d\n", rbuf.data[j]);
    }

}

And here is my output:

msgget: Calling msgget(0x4d2,01666)
pthread_create() for thread 1 returns: 0
pthread_create() for thread 2 returns: 0
msgget: msgget succeeded: msqid = 0
msgget: msgget succeeded: msqid = 0
msgget: msgget succeeded: msqid = 0
Data sent
0
1
2
3
4
5
6
7
8
9
10
11
12
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

This

buf_length = SIZE;

sets the message text size to 50 bytes .

Yet the structure is defined as

typedef struct msgbuf {
         long    mtype;
         int    data[SIZE];
} data_buf;

data is 50 int elements. That's not 50 bytes - it's almost certainly 200 bytes, with a 4-byte/32-bit int .

And 50 bytes is enough to hold 12 1/2 4-byte int values, explaining why you see a count up to 12.

Replace buf_length = SIZE with buf_length = sizeof( data_buf );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM