C Linux pthreads:使用消息队列将数据从一个线程发送到另一个线程会产生意外结果

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

我正在编写一个程序,它将使用消息队列将 50 个整数从一个线程传输到另一个线程,并且在接收到整数后,接收器线程将打印它们。

目前接收线程打印前 13 个整数(0,1,2..12),但之后它只打印全 0。

到目前为止,这是我的代码:

#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]);
    }

}

这是我的输出:

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

这个

buf_length = SIZE;

将消息文本大小设置为 50 字节

然而结构定义为

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

data 是 50 int 个元素。那不是 50 字节——几乎可以肯定是 200 字节,带有 4-byte/32-bit int.

50 个字节足以容纳 12 1/2 个 4 字节 int 值,这解释了为什么您会看到计数达到 12。

buf_length = SIZE替换为buf_length = sizeof( data_buf );