Я использую простую реализацию очереди и пытаюсь создать простую программу, которая имеет два потока: первый в очереди событий в очереди, а второй обрабатывает их.Я использую мьютексы, чтобы избежать проблем с синхронизацией.Тем не менее, я все еще получаю довольно часто (не всегда) ошибки сегментации.
Имейте в виду, я также создал свои коды, используя опцию -D_REENTRANT
.Кроме того, код прекрасно работает, если очередь / очередь вызывается только из одного потока.
Вот простой код, который показывает, как я синхронизирую вещи:
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;
}
Это segfaults на линии*value = q->first->data;
в dequeue
.
Спасибо!