【发布时间】:2021-08-19 16:15:05
【问题描述】:
我已经实现了一个队列系统来将数据从一个线程传输到我的主循环,我在此处附加了该代码
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pthread.h"
#define MAX_QUEUE_SIZE (100)
#define MAX_DATA_SIZE (10000)
// A structure to represent a queue
struct Queue {
unsigned int front, rear, size;
unsigned int capacity;
unsigned int ele_size;
char* array;
};
//queue lock
pthread_mutex_t qlock;
// function to create a queue of given capacity.
// It initializes size of queue as 0
struct Queue* createQueue(unsigned int capacity, unsigned int ele_size)
{
struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
queue->capacity = capacity;
queue->front = queue->size = 0;
queue->rear = capacity - 1;
queue->ele_size = ele_size;
queue->array = (char*)malloc(queue->capacity * ele_size);
if(queue->array == NULL)
{
fflush(stdout);
printf("\n Fail to allocate memory..!!\n");
fflush(stdout);
return 0;
}
memset(queue->array, 0, (queue->capacity * sizeof(ele_size)));
if (pthread_mutex_init(&qlock, NULL) != 0) {
printf("\n Fail to init mutex\n");
fflush(stdout);
return 0;
}
return queue;
}
// Queue is full when size becomes equal to the capacity
int isFull(struct Queue* queue)
{
return (queue->size == queue->capacity);
}
// Queue is empty when size is 0
int isEmpty(struct Queue* queue)
{
return (queue->size == 0);
}
// Function to know number of arrays in queue
int no_elements(struct Queue* queue)
{
unsigned int size = 0;
pthread_mutex_lock(&qlock);
size = queue->size;
pthread_mutex_unlock(&qlock);
return size;
}
void* getnode(struct Queue* queue)
{
char *node = malloc(queue->ele_size);
return node;
}
void freenode(char *node)
{
if(node != NULL)
free(node);
}
// Function to add an item to the queue.
void enqueue(struct Queue* queue, void *data, unsigned int size)
{
pthread_mutex_lock(&qlock);
if (isFull(queue))
{
pthread_mutex_unlock(&qlock);
return;
}
queue->rear = (queue->rear + 1) % queue->capacity;
//printf(" size is %d index is %d\n",(queue->rear * queue->ele_size),queue->rear);
//fflush(stdout);
memmove(&(queue->array[queue->rear * queue->ele_size]), data, size);
queue->size = queue->size + 1;
pthread_mutex_unlock(&qlock);
return;
}
// Function to remove an item from queue.
// It changes front and size
void dequeue(struct Queue* queue, void* data, unsigned int size)
{
pthread_mutex_lock(&qlock);
if (isEmpty(queue))
{
pthread_mutex_unlock(&qlock);
return;
}
if(data == NULL)
{
printf("\n Invalid args..!!\n");
pthread_mutex_unlock(&qlock);
return;
}
memcpy(data, &(queue->array[queue->front * queue->ele_size]), size);
queue->front = (queue->front + 1) % queue->capacity;
queue->size = queue->size - 1;
pthread_mutex_unlock(&qlock);
return;
}
void deleteQueue(struct Queue* queue)
{
pthread_mutex_lock(&qlock);
if(queue->array != NULL)
free(queue->array);
pthread_mutex_unlock(&qlock);
}
我有一个函数可以从队列中取出数据,并且入队发生在不同的 pthread 中
出队的功能是
SenderData* Dequeue_elements_rec(struct Queue*structqueuehandle)
{
char *deq_node = getnode(structqueuehandle);
dequeue(structqueuehandle, deq_node, (sizeof(SenderData) + 10000));
SenderData *data2 = (SenderData*)malloc(sizeof(SenderData));
memcpy(data2, deq_node, sizeof(SenderData));
data2->Data = malloc(data2->DataSize);
memcpy(data2->Data, deq_node + sizeof(SenderData), data2->DataSize);
printf("cmd: %d size: %d\n", data2->CommandCode, data2->DataSize);
SenderData *test_ptr = (SenderData*)data2;
printf("cmd code from msg_ptr is %d\n",test_ptr->DataSize);
printf("cmd code from msg_ptr is %d\n",test_ptr->CommandCode);
int *testi = (int*)data2->Data;
printf("dq---%d %d %d data size: %d\n", testi[0], testi[1], testi[209], data2->DataSize);
fflush(stdout);
freenode(deq_node);
return test_ptr;
}
发送方数据的定义如下
typedef struct SenderData {
unsigned int CommandCode;
unsigned int DataSize;
void *Data;
//unsigned char DestID; **
} SenderData;
我的主要代码在这里
int main (int argc, char *argv[])
{
config_rec_engine();
usleep(1000*1000);
while(1)
{
if(no_elements(rec_queue_hndl)>0)
{
printf("inside deq \n");
SenderData *temp=Dequeue_elements_rec(rec_queue_hndl);
//printf("Code is %d\n",temp->CommandCode);
fflush(stdout);
}
else
{
usleep(1000*1000);
}
}
deleteQueue(rec_queue_hndl);
return 0;
}
问题是,当我尝试从我的主线程打印出列数据时,我得到错误和类似的分段错误,但是当我尝试从我的出列函数打印相同的数据时,我得到了正确的数据。我只是将接收到的指针作为函数的返回传递。
这是来自名为 data2 的出队数据元素中的 printf,它正确出现
data from from data2 cmd code is : 240 size: 840
这是语句分配的指针中的 printf
SenderData test_ptr = (SenderData)data2;
这里的 cdata 也是正确的,但是当我从电源中的指针打印时,它不起作用
Size from msg_ptr is 840
cmd code from msg_ptr is 240
dq---207 1 209 data size: 840
........控制台............ .......
>>>>>>REC_Engine_Started<<<<<<<
malloced************
add single data
Sending Ack
inside deq
data from from data2 cmd code is : 240 size: 840
Size from msg_ptr is 840
cmd code from msg_ptr is 240
dq---207 1 209 data size: 840
0 [main] udpexx1 822 cygwin_exception::open_stackdumpfile: Dumping stack trace to udpexx1.exe.stackdump
这是我创建队列的地方
void config_rec_engine(void)
{
skt=CSPL__CreateSocket();
CSPL_re_use(skt);
Bindtoport(skt,65533);
Add_mul_cast_member(skt,"192.168.1.11","225.1.1.2");
//// Queue ////////
rec_queue_hndl = createQueue(1000, (sizeof(SenderData) + 10000) );
rec_thread1_ret = pthread_create(&rec_thread_1, NULL, Receiver_thread,(void*) rec_message1);
//pthread_join(Send_thread_1, NULL);
}
作为调试的一部分,我将 data2 设为全局并尝试在我的电源中获取数据,这没有任何问题
int main (int argc, char *argv[])
{
config_rec_engine();
usleep(1000*1000);
while(1)
{
if(no_elements(rec_queue_hndl)>0)
{
printf("inside deq \n");
SenderData *temp=Dequeue_elements_rec(rec_queue_hndl);
printf("print from mains code is %d\n",data2->CommandCode);
fflush(stdout);
}
else
{
usleep(1000*1000);
}
}
deleteQueue(rec_queue_hndl);
return 0;
}
我的控制台打印是.....................
malloced************
add single data
Sending Ack
inside deq
data from from data2 cmd code is : 1291 size: 840
Size from msg_ptr is 840
cmd code from msg_ptr is 1291
dq---1258 1 209 data size: 840
print from mains code is 1291
预期的数据是,这是在一个while循环中并通过udp套接字连续发送
cont[0]++;
cont[1] = 1;
cont[209] = 209;
data.CommandCode=33+cont[0];
data.DataSize=sizeof(cont);
data.Data=cont;
Enqueue_elements(queue_hndl, &data);
【问题讨论】:
-
我正在编辑我的代码以显示创建队列部分,我正在创建大小为 10000 的队列
-
更好,但我们仍然需要查看
Receiver_thread函数和rec_message1的设置/初始化。理想情况下,足以干净地下载和编译并且 [有点] 可运行。CSPL_*是非标准的[至少对我来说],所以我已经在我已经拥有的副本中添加了它。我们希望能够运行程序实际上不必连接到多播组。那么,什么是导致故障的代表性数据? -
@CraigEstey 这是我要发送的数据,对不起,我不知道如何在此评论中格式化 cont[0]++;续[1] = 1;续[209] = 209; data.CommandCode=33+cont[0]; data.DataSize=sizeof(续);数据.数据=续; enqueue_elements(queue_hndl, &data);
-
@CraigEstey 我已经用预期数据更新了我的问题
-
好吧,我猜那是
Receiver_thread的正文???cont和data的[定义]是什么?但是,这也引入了对Enqueue_elements[我们没有] 的调用。到目前为止,我计算了大约 290 行源代码。这足够小,您可以 [并且应该] 在底部的 single 代码块中发布 所有 代码。它应该编译干净
标签: c pointers struct pthreads dump