[英]Pointer loses its value when called in different thread
我已经实现了一个队列系统来将数据从一个线程传输到我的主循环,我在此处附加了该代码
#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);
}
我有一个 function 将数据从队列中取出,并且入队发生在不同的 pthread 中
用于出队的 function 是
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;
}
问题是,当我尝试从我的主线程打印出列数据时,我得到错误和类似的分段错误,但是当我尝试从我的出列 function 打印相同的数据时,我得到了正确的数据。 我只是将接收到的指针作为 function 的返回传递。
这是来自名为 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);
警告:如果不查看整个代码,很难确定,但是...
在Dequeue_elements_rec
中,我们有:
char *deq_node = getnode(structqueuehandle);
dequeue(structqueuehandle, deq_node, (sizeof(SenderData) + 10000));
getnode
执行长度为queue->ele_size
malloc
如果没有更多代码,我们真的不知道那个长度是多少。 所以,我认为它很小(例如) sizeof(SenderData)
,所以 30 [or so] 字节。
当我们调用dequeue
时,第三个参数是: (sizeof(SenderData) + 10000)
,因此传递的长度约为 10000 字节。
在dequeue
中,我们有:
memcpy(data, &(queue->array[queue->front * queue->ele_size]), size);
因此, data
指向一个小区域。 而且,我们正在从queue->array
复制。
但是, size
的值至少为 10000 字节。 因此,除非在[更早的地方]调用createQueue
ele_size
为 10000 字节,否则此memcpy
将在写入data
或尝试从源参数中获取时出现段错误。
更新:
为了方便访问,我提供了我的代码链接,我更新了我的问题 – RHKP
好的,我从您的 Google Drive 下载了.zip
文件,并解压缩了它们。
我必须做一些清理工作以使其在 Linux 下的系统上编译。 我不得不将一些 function 原型添加到一些.h
文件中。 而且,我必须将struct Queue
定义从my_queue.c
移到my_queue.h
中。 而且,我不得不从my_queue.c
中删除“守卫” #ifndef
,因为它与my_queue.h
中的相冲突
另外,我在构建结构上遇到了问题,所以我忽略了所有复杂的gcc
命令行选项,只是手动构建了程序。
请注意,我必须调整单播地址(例如192.168.xy
在我的环境中播放效果不太好)。 我在这里将其调整为10.xyz
地址,但这也不起作用。 我不得不接受127.xyz
。
当我最后一次使用多播时,我使用239.xyz
,它是“本地组织”[vs. “预订的”]。 我一开始就切换到那个。
完成所有这些之后,我在单独的终端 window 中运行每个程序。
两个程序都运行没有错误!
所以,我只能想知道您设置中的某些.o
文件是否没有重建(例如,我会做一个make clean
)。
或者,这是一些cygwin
特定的问题。 我建议你在 linux 机器上试试看。 您也可以尝试使用mingw
构建它。 或者,安装WSL2
并作为虚拟机运行(例如) ubuntu
[或者,其他一些虚拟机管理程序,如virtualbox
、 xen
、 vmware
等]。
这是Host
程序的output:
UNI_ADDRESS=127.0.0.11
MCAST_ADDRESS=225.1.1.2
>>>>>>REC_Engine_Started<<<<<<<
>>>>>>Sender_Engine_Started<<<<<<<
malloced************
add single data
Sending Ack
inside deq
print from mains code is 34
dqffff---1 1 209 data size: 840
malloced************
add single data
Sending Ack
inside deq
print from mains code is 35
dqffff---2 1 209 data size: 840
malloced************
add single data
Sending Ack
inside deq
print from mains code is 36
dqffff---3 1 209 data size: 840
malloced************
add single data
Sending Ack
inside deq
print from mains code is 37
dqffff---4 1 209 data size: 840
malloced************
add single data
Sending Ack
inside deq
print from mains code is 38
dqffff---5 1 209 data size: 840
这是receiver
程序的output:
UNI_ADDRESS=127.0.0.10
MCAST_ADDRESS=225.1.1.2
>>>>>>Sender_Engine_Started<<<<<<<
CMD Code 34---Size 840Sending- 209
data flag 0
single packet data sent
CMD Code 35---Size 840Sending- 209
data flag 0
single packet data sent
CMD Code 36---Size 840Sending- 209
data flag 0
single packet data sent
CMD Code 37---Size 840Sending- 209
data flag 0
single packet data sent
CMD Code 38---Size 840Sending- 209
data flag 0
single packet data sent
这是我所做的更改的diff -ru
output :
diff -ru unzip/Host/Debug/src/subdir.mk fixed/Host/Debug/src/subdir.mk
--- unzip/Host/Debug/src/subdir.mk 2021-06-01 14:31:27.901262121 -0400
+++ fixed/Host/Debug/src/subdir.mk 2021-06-01 13:42:58.408494344 -0400
@@ -13,11 +13,15 @@
./src/udpexx1.d
+SADIR := $(HOME)/tmp/queue/Host/SocketAPI
+ILIST += -I$(SADIR)
+VPATH := $(SADIR)
+
# Each subdirectory must supply rules for building sources it contributes
src/%.o: ../src/%.c src/subdir.mk
@echo 'Building file: $<'
@echo 'Invoking: Cygwin C Compiler'
- gcc -I"C:\cygwin64\bin" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -o "$@" "$<"
+ gcc $(ILIST) -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$@" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
diff -ru unzip/Host/SocketAPI/Global_dat.h fixed/Host/SocketAPI/Global_dat.h
--- unzip/Host/SocketAPI/Global_dat.h 2021-06-01 14:31:27.933261450 -0400
+++ fixed/Host/SocketAPI/Global_dat.h 2021-06-01 17:01:59.775120694 -0400
@@ -3,6 +3,20 @@
//HSFC UDP Data Packet definition
+//Add_mul_cast_member(skt,"192.168.1.11","225.1.1.2");
+#if UNI_ORIG == 1
+#define UNI_ADDRESS "192.168.1.11"
+#elif UNI_ORIG == 2
+#define UNI_ADDRESS "10.0.0.96"
+#else
+#define UNI_ADDRESS "127.0.0.11"
+#endif
+#ifdef MCAST_ORIG
+#define MCAST_ADDRESS "225.1.1.2"
+#else
+#define MCAST_ADDRESS "239.1.1.2"
+#endif
+
typedef struct HSFC_UDP_Packet {
unsigned short Year; // year
unsigned char Month; // months
diff -ru unzip/Host/SocketAPI/my_queue.c fixed/Host/SocketAPI/my_queue.c
--- unzip/Host/SocketAPI/my_queue.c 2021-06-01 20:13:36.000000000 -0400
+++ fixed/Host/SocketAPI/my_queue.c 2021-06-01 13:53:01.173779495 -0400
@@ -1,5 +1,5 @@
-#ifndef MY_QUEUE_H // Include guard
-#define MY_QUEUE_H
+//#ifndef MY_QUEUE_H // Include guard
+//#define MY_QUEUE_H
#include <limits.h>
#include <stdio.h>
@@ -7,21 +7,16 @@
#include <string.h>
#include "pthread.h"
+#include <my_queue.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;
-int no_elements(struct Queue* queue);
+//int no_elements(struct Queue* queue);
+
// 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)
@@ -152,4 +147,4 @@
}
-#endif
+//#endif
diff -ru unzip/Host/SocketAPI/my_queue.h fixed/Host/SocketAPI/my_queue.h
--- unzip/Host/SocketAPI/my_queue.h 2021-06-01 20:14:00.000000000 -0400
+++ fixed/Host/SocketAPI/my_queue.h 2021-06-01 13:02:31.610344349 -0400
@@ -10,6 +10,15 @@
#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;
+};
+
+int no_elements(struct Queue* queue);
struct Queue* createQueue(unsigned int capacity, unsigned int ele_size);
void deleteQueue(struct Queue* queue);
diff -ru unzip/Host/SocketAPI/Receiver.c fixed/Host/SocketAPI/Receiver.c
--- unzip/Host/SocketAPI/Receiver.c 2021-06-01 14:31:27.944261219 -0400
+++ fixed/Host/SocketAPI/Receiver.c 2021-06-01 16:55:36.010174477 -0400
@@ -240,19 +240,24 @@
return 0;
}
+
void config_rec_engine(void)
{
+ printf("UNI_ADDRESS=%s\n",UNI_ADDRESS);
+ printf("MCAST_ADDRESS=%s\n",MCAST_ADDRESS);
skt=CSPL__CreateSocket();
CSPL_re_use(skt);
Bindtoport(skt,65533);
+#if 0
Add_mul_cast_member(skt,"192.168.1.11","225.1.1.2");
+#else
+ Add_mul_cast_member(skt,UNI_ADDRESS,MCAST_ADDRESS);
+#endif
//// Queue ////////
rec_queue_hndl = createQueue(1000, (sizeof(SenderData) + 5000) );
- rec_thread1_ret = pthread_create(&rec_thread_1, NULL, Receiver_thread,(void*) rec_message1);
+ rec_thread1_ret = pthread_create(&rec_thread_1, NULL,
+ Receiver_thread,(void*) rec_message1);
//pthread_join(Send_thread_1, NULL);
-
-
-
}
void *Receiver_thread(void *msg_ptr) // Sender Engine
@@ -293,10 +298,13 @@
{
char *deq_node = getnode(structqueuehandle);
dequeue(structqueuehandle, deq_node, (sizeof(SenderData) + 5000));
+
Received_data = (SenderData*)malloc(sizeof(SenderData));
memcpy(Received_data, deq_node, sizeof(SenderData));
+
Received_data->Data = malloc(Received_data->DataSize);
memcpy(Received_data->Data, deq_node + sizeof(SenderData), Received_data->DataSize);
+
//printf("data from from data2 cmd code is : %d size: %d\n", Received_data->CommandCode, Received_data->DataSize);
test_ptr = (SenderData*)Received_data;
//printf("Size from msg_ptr is %d\n",test_ptr->DataSize);
diff -ru unzip/Host/SocketAPI/Receiver.h fixed/Host/SocketAPI/Receiver.h
--- unzip/Host/SocketAPI/Receiver.h 2021-06-01 14:31:27.946261177 -0400
+++ fixed/Host/SocketAPI/Receiver.h 2021-06-01 13:04:03.469411136 -0400
@@ -21,6 +21,7 @@
//#include "Globals.h"
+SenderData* Dequeue_elements_rec(struct Queue*structqueuehandle);
void Enqueue_elements_rec(struct Queue*structqueuehandle,SenderData* sending_packet);
void CSPL_SOK_ERROR(int error_no);
int CSPL__CreateSocket(void);
diff -ru unzip/Host/SocketAPI/sender.c fixed/Host/SocketAPI/sender.c
--- unzip/Host/SocketAPI/sender.c 2021-06-01 14:31:27.959260905 -0400
+++ fixed/Host/SocketAPI/sender.c 2021-06-01 14:11:39.174222789 -0400
@@ -293,7 +293,11 @@
*/
memset((char *) &groupSock, 0, sizeof(groupSock));
groupSock.sin_family = AF_INET;
+#if 0
groupSock.sin_addr.s_addr = inet_addr("225.1.1.2");
+#else
+ groupSock.sin_addr.s_addr = inet_addr(MCAST_ADDRESS);
+#endif
groupSock.sin_port = htons(65533);
/*
@@ -315,7 +319,11 @@
* The IP address specified must be associated with a local,
* multicast-capable interface.
*/
+#if 0
localInterface.s_addr = inet_addr("192.168.1.10");
+#else
+ localInterface.s_addr = inet_addr(UNI_ADDRESS);
+#endif
if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&localInterface,
sizeof(localInterface)) < 0) {
diff -ru unzip/Host/src/udpexx1.c fixed/Host/src/udpexx1.c
--- unzip/Host/src/udpexx1.c 2021-06-01 14:31:27.963260821 -0400
+++ fixed/Host/src/udpexx1.c 2021-06-01 13:06:01.845920123 -0400
@@ -1,4 +1,8 @@
+#if 0
#include "my_queue.h"
+#else
+#include <my_queue.h>
+#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
@@ -9,6 +13,7 @@
#include <netinet/in.h>
#include "Global_dat.h"
#include "Receiver.h"
+#include "sender.h"
//#include "sender.c"
@@ -36,10 +41,16 @@
{
printf("inside deq \n");
+#if 0
SenderData *temp=Dequeue_elements_rec(rec_queue_hndl);
+#else
+ SenderData *Received_data=Dequeue_elements_rec(rec_queue_hndl);
+#endif
+
printf("print from mains code is %d\n",Received_data->CommandCode);
int *testi = (int*)Received_data->Data;
- printf("dqffff---%d %d %d data size: %d\n", testi[0], testi[1], testi[209], Received_data->DataSize);
+ printf("dqffff---%d %d %d data size: %d\n",
+ testi[0], testi[1], testi[209], Received_data->DataSize);
fflush(stdout);
}
diff -ru unzip/receiver/api_include/Globals.h fixed/receiver/api_include/Globals.h
--- unzip/receiver/api_include/Globals.h 2021-06-01 14:31:28.006259918 -0400
+++ fixed/receiver/api_include/Globals.h 2021-06-01 17:02:05.188007105 -0400
@@ -1,4 +1,21 @@
//HSFC UDP Data Packet definition
+#ifndef _api_globals_h_
+#define _api_globals_h_
+
+//Add_mul_cast_member(skt,"192.168.1.11","225.1.1.2");
+#if UNI_ORIG == 1
+#define UNI_ADDRESS "192.168.1.10"
+#elif UNI_ORIG == 2
+#define UNI_ADDRESS "10.0.0.96"
+#else
+#define UNI_ADDRESS "127.0.0.10"
+#endif
+#ifdef MCAST_ORIG
+#define MCAST_ADDRESS "225.1.1.2"
+#else
+#define MCAST_ADDRESS "239.1.1.2"
+#endif
+
typedef struct HSFC_UDP_Packet {
unsigned short Year; // year
unsigned char Month; // months
@@ -44,3 +61,5 @@
char Data[0];
//unsigned char DestID; **
} SenderDataA;
+
+#endif
diff -ru unzip/receiver/api_include/sender.c fixed/receiver/api_include/sender.c
--- unzip/receiver/api_include/sender.c 2021-06-01 14:31:28.025259520 -0400
+++ fixed/receiver/api_include/sender.c 2021-06-01 16:54:20.968749441 -0400
@@ -1,5 +1,7 @@
#include<pthread.h>
-stop_nw_global=0;
+#include <Globals.h>
+
+//stop_nw_global=0;
// related to data and packets
HSFC_UDP_Packet headder;
@@ -246,6 +248,8 @@
int start_sender_engine(void)
{
+ printf("UNI_ADDRESS=%s\n",UNI_ADDRESS);
+ printf("MCAST_ADDRESS=%s\n",MCAST_ADDRESS);
thread1_ret = pthread_create(&Send_thread_1, NULL, Sender_thread,(void*) message1);
//pthread_join(Send_thread_1, NULL);
//// Queue ////////
@@ -285,7 +289,11 @@
*/
memset((char *) &groupSock, 0, sizeof(groupSock));
groupSock.sin_family = AF_INET;
+#if 0
groupSock.sin_addr.s_addr = inet_addr("225.1.1.2");
+#else
+ groupSock.sin_addr.s_addr = inet_addr(MCAST_ADDRESS);
+#endif
groupSock.sin_port = htons(65533);
/*
@@ -307,7 +315,11 @@
* The IP address specified must be associated with a local,
* multicast-capable interface.
*/
+#if 0
localInterface.s_addr = inet_addr("192.168.1.10");
+#else
+ localInterface.s_addr = inet_addr(UNI_ADDRESS);
+#endif
if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&localInterface,
sizeof(localInterface)) < 0) {
diff -ru unzip/receiver/src/nwudp.c fixed/receiver/src/nwudp.c
--- unzip/receiver/src/nwudp.c 2021-06-01 06:22:04.000000000 -0400
+++ fixed/receiver/src/nwudp.c 2021-06-01 14:14:02.401213180 -0400
@@ -6,6 +6,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+
#include "my_queue.h"
#include "Globals.h"
#include "sender.h"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.