我正在使用一个简单的队列实现,我正在尝试创建一个包含两个线程的简单程序:队列中的第一个队列事件和第二个队列事件处理它们。我正在使用互斥锁来避免同步问题。但是,我仍然经常(并非总是)出现分段错误。
请注意,我也使用-D_REENTRANT
选项构建了代码。此外,如果仅从一个线程调用queue / dequeue,则代码可以正常工作。
这是一个简单的代码,显示了我如何同步这些东西:
int main(void) {
init_queue(&my_queue);
pthread_t thread_queue, thread_process;
int iret1, iret2;
iret1 = pthread_create( &thread_queue, NULL, svetlin_queue_events, (void*) NULL);
iret2 = pthread_create( &thread_process, NULL, svetling_process_events, (void*) fb);
pthread_join(thread_queue, NULL);
pthread_join(thread_process, NULL);
}
排队功能:
void svetlin_queue_events(void * v) {
int fd;
if ((fd = open("/dev/input/mouse1", O_RDONLY)) == -1) {
printf("error with touchscreen device\n");
exit(1);
}
struct input_event ev;
struct input_event *being_sent;
int rd;
while (1) {
read(fd, &ev, sizeof(struct input_event));
being_sent = malloc(sizeof(struct input_event));
memcpy(being_sent, &ev, sizeof(struct input_event));
pthread_mutex_lock(&my_mutex);
enqueue(&my_queue, being_sent);
pthread_mutex_unlock(&my_mutex);
printf("enqueueing...\n");
}
}
和处理功能:
void svetling_process_events(void *v) {
printf("FB pointer is: %p\n", fb);
int x, y = 0;
int has_item = 0;
struct input_event **being_fetched;
struct input_event *ev;
while(1) {
pthread_mutex_lock(&my_mutex);
has_item = dequeue(&my_queue, being_fetched);
pthread_mutex_unlock(&my_mutex);
if (has_item) {
ev = *being_fetched;
printf("dequeueing...\n");
if (ev->type == 3) {
if (ev->code == 0) {
x = ev->value;
}
if (ev->code == 1) {
y = ev->value;
}
}
}
}
}
我希望我没有用如此多的代码压倒你,但这真的很简单。
所以我的问题是关于同步我做错了什么?
谢谢!
这是队列实现:
struct queue_node
{
struct queue_node *next;
void *data;
};
struct queue
{
struct queue_node *first;
struct queue_node *last;
};
int enqueue(struct queue *q, void * const value)
{
struct queue_node *node = malloc(sizeof(struct queue_node));
if (node == NULL) {
errno = ENOMEM;
return 1;
}
node->data = value;
if (q->first == NULL) {
q->first = q->last = node;
} else {
q->last->next = node;
q->last = node;
}
node->next = NULL;
return 0;
}
int dequeue(struct queue *q, void **value)
{
if (!q->first) {
value = NULL;
return 0;
}
*value = q->first->data;
q->first = q->first->next;
return 1;
}
void init_queue(struct queue *q)
{
q->first = q->last = NULL;
}
int queue_empty_p(const struct queue *q)
{
return q->first == NULL;
}
它在*value = q->first->data;
中的dequeue
行上进行了段错误。
谢谢!
答案 0 :(得分:2)
一个小问题是:
if (!q->first) {
*value = NULL;
return 0;
}
(注意添加的星号)。
主要问题似乎是你没有在process_events函数中为*being_fetched
分配内存。
说实话,我会将该变量的类型更改为struct input_event *being_fetched
,并将其地址简单地传递给dequeue
:has_item = dequeue(&my_queue, &being_fetched)
。这也可以让你摆脱ev
作为一个单独的变量。
答案 1 :(得分:1)
正如aix所说,你没有初始化* being_fetched。但我认为你最好不同地定义它:
struct input_event *being_fetched;
...
has_item = dequeue(&my_queue, &being_fetched);
...
ev = being_fetched;
然后绝对确定你修复了aix提到的另一个错误,否则你不会将空指针退回到函数之外。