gpt4 book ai didi

c - 使用邮箱实现线程间通信的问题

转载 作者:行者123 更新时间:2023-11-30 15:33:53 27 4
gpt4 key购买 nike

我正在尝试使用邮箱(即共享消息缓冲区)实现线程间通信。

我已经编写了以下函数,用于将消息存入邮箱和从邮箱中取出,但我确信我遗漏了一些小东西(但是,我不知道是什么)。当我尝试从邮箱检索消息时,消息长度以某种方式设置为 0,而理想情况下它应该读取缓冲区中的节点。我的邮箱功能代码、测试程序及其预期输出以及我得到的输出如下:

void mbox_deposit(mbox *mb, char *msg, int len)
{
struct msg *temp, *temp1;
temp = GetNewMsgNode(len);

// temp = mb->msg_queue;

sem_wait(mb->sem_mbox);
// lock mailbox - critical section locked
if(mb->msg_queue == NULL)
{
temp->message = msg;
temp->length = len;
temp->next = NULL;

mb->msg_queue = temp;
}
else
{
temp->message = msg;
temp->length = len;
temp->next = NULL;

temp1 = mb->msg_queue;
while(temp1->next != NULL)
temp1 = temp1->next;

temp1->next = temp;

}
// unlock mailbox - critical section unlocked
sem_signal(mb->sem_mbox);
}


void mbox_withdraw(mbox *mb, char *msg, int *len)
{

// struct msg *temp;
// temp = mb->msg_queue;

sem_wait(mb->sem_mbox);
// lock mailbox - critical section locked
if(mb->msg_queue == NULL)
{
printf("No message to withdraw!");
return;
}
else
{
// withdraw first message from message queue
// temp = temp->next;

len = &(mb->msg_queue->length);

printf("%d", len);

if(len != 0)
{
msg = mb->msg_queue->message;

// make the msg_queue head point to the new first message in the queue after the first message has been removed
if(mb->msg_queue->next != NULL)
mb->msg_queue = mb->msg_queue->next;
}

// free(temp);
}
// unlock mailbox - critical section unlocked
sem_signal(mb->sem_mbox);

}

测试程序及其预期输出如下:

#include <stdio.h>
#include <stdlib.h>
#include "ud_thread.h"

mbox *mb;
char *msg[2] = {"hello world...", "bye, bye"};

void producer(int id)
{
int i;
char mymsg[30];

for (i = 0; i < 2; i++) {
sprintf(mymsg, "%s - tid %d", msg[i], id);
printf("Producer (%d): [%s] [length=%d]\n", id, mymsg, strlen(mymsg));
mbox_deposit(mb, mymsg, strlen(mymsg));
}

t_terminate();
}

void consumer(int id)
{
int i;
int len;
char mesg[1024];

for (i = 0; i < 4; i++) {
mbox_withdraw(mb, mesg, &len);
printf("Message from mailbox: [%s]\n", mesg);
}

t_terminate();
}

int main(void) {

t_init();

mbox_create(&mb);
t_create(producer, 1, 1);
t_create(producer, 2, 1);
t_create(consumer, 3, 1);
t_yield();
mbox_destroy(&mb);

t_shutdown();
printf("Done with mailbox test...\n");

return 0;
}

预期输出:

Producer (1): [hello world... - tid 1] [length=22]
Producer (1): [bye, bye - tid 1] [length=16]
Producer (2): [hello world... - tid 2] [length=22]
Producer (2): [bye, bye - tid 2] [length=16]
Message from mailbox: [hello world... - tid 1]
Message from mailbox: [bye, bye - tid 1]
Message from mailbox: [hello world... - tid 2]
Message from mailbox: [bye, bye - tid 2]
Done with mailbox test...

但是,我最终通过邮箱功能得到的是:

Producer (1): [hello world... - tid 1] [length=22]
Producer (1): [bye, bye - tid 1] [length=16]
Producer (2): [hello world... - tid 2] [length=22]
Producer (2): [bye, bye - tid 2] [length=16]
Message from mailbox: []
Message from mailbox: []
Message from mailbox: []
Message from mailbox: []
Done with mailbox test...

对于我在这里可能缺少的内容有什么建议吗?

最佳答案

此分配对调用者没有影响:

void mbox_withdraw(mbox *mb, char *msg, int *len)
....
msg = mb->msg_queue->message;

您只需更改自己的指针副本msg。这是一个关于 C FAQ 的著名问题的复杂示例。 (或者您可能试图以错误的方式复制字符串)。

您可能想做类似的事情:

memcpy(msg, b->msg_queue->message, ...);

或者,如果您已经信任邮箱中的字符串(您可能在这样的测试程序中执行此操作),则只需使用 strcpy

<小时/>

编辑

在你的代码中msg只是一个变量,一个指针。当您调用该函数时,它指向 char mesg[1024] 中的数据。但是,如果您说 msg = mb->msg_queue->message,您就会使变量 msg 指向其他内容。在函数结束时,msg 指向哪里就不再重要了;重要的是对调用者的影响。

关于c - 使用邮箱实现线程间通信的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23549448/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com