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 );
我正在编写一个程序,它将使用消息队列将 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 );