记录一个多线程用来收发数据的数据结构,以及一点踩坑日记
正文
我有两个线程,一个线程专门用来收数据,一个线程专门用来发数据,因此我有两个list结构的链表,一个用来收数据,一个用来发数据,暂称为recvlist和sendlist;为了确保线程安全,我使用了两个锁。
代码逻辑是这样的:
recvlist在一般情况下含有多个元素,而sendlist正常情况下是空的。两个线程同时工作,每次接收线程在接收数据的时候,就弹出recvlist头部的元素,填充之后,就将该元素放入sendlist中。而发送线程检测到sendlist不为空时,就将sendlist中的元素弹出来,发送出去。循环往复
逻辑是没毛病的,下面看实际实现过程:
首先是对两个list存取数据的操作:
void buf_put(std::list<type* >&list, type* element, pthread_mutex& mutex)
{
// 加锁
pthread_mutex_lock(mutex);
// 将元素压入list尾部:如果是recvlist,尾部数据已经不需要再使用了
list.push_back(element);
// 解锁
pthread_mutex_unlock(mutex);
}
type* buf_take(std::list<type* >&list, pthread_mutex& mutex)
{
// 加锁
pthread_mutex_lock(mutex);
// 获取当前元素并弹出
type* element = list.front();
list.pop_front();
// 解锁
pthread_mutex_unlock(mutex);
// 返回,外部接收
return element;
}
错误描述
根据排查,发现在进行buf_put()操作的时候,一切正常,sendlist中每次压入的也都是正常的数据,但对sendlist进行buf_put操作的时候,大部分时候取到的数据都是错误的,只有偶尔取到的数据是正常的。集中体现在element->len的值为 -1。
错误原因
原因已经找到,错误的地方并不在于对两个list存取数据的操作...原因在于如果使用指针作为函数的参数进行传递,如:
void functionA()
{
demo_struct demo1;
demo_struct* ptr1 = &demo1;
functionB(ptr1);
}
void functionB(demo_struct* ptr)
{
// TODO:
}
在函数functionB()中,ptr作为一个指针被传递过来,在上面例子中,指针ptr指向结构体demo1,通过对ptr进行操作,可以修改demo1中数据的值,可以修改指针ptr指向的地址的值,但是,在函数functionB()中,无法修改指针ptr本身的值,因为它本身是个指针,因此指针的值指的就是指针本身的地址。
如果想在一个函数中修改另一个函数中定义的指针的值,那么在函数间传递的参数应该是这个指针的指针,而非这个指针本身。示例如下:
#include <stdio.h>
typedef struct demo_struct{
char buf[10];
int len;
} demo_struct;
void functionB(demo_struct** ptr)
{
fprintf(stdout, "access into functionB()\n");
*ptr = NULL;
fprintf(stdout, "ptr = NULL\n");
}
void functionA()
{
demo_struct demo1;
demo_struct* demo_ptr1 = &demo1;
if (NULL != demo_ptr1)
fprintf(stdout, "test start!\n");
functionB(&demo_ptr1);
if (demo_ptr1 == NULL)
fprintf(stdout, "test successfully\n");
}
int main()
{
functionA();
return 0;
}
评论
0 评论