Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用pthreads互斥体的C中的同步问题_C_Synchronization_Pthreads_Mutex - Fatal编程技术网

使用pthreads互斥体的C中的同步问题

使用pthreads互斥体的C中的同步问题,c,synchronization,pthreads,mutex,C,Synchronization,Pthreads,Mutex,我正在使用一个简单的队列实现,我正在尝试制作一个简单的程序,它有两个线程:第一个线程是队列上的队列事件,第二个线程处理它们。我使用互斥来避免同步问题。然而,我仍然经常(并非总是)遇到分段错误 请注意,我也使用-D_可重入选项构建代码。此外,如果仅从一个线程调用queue/dequeue,则该代码可以很好地工作 下面是一段简单的代码,显示了我是如何同步这些内容的: int main(void) { init_queue(&my_queue); pthread_t thre

我正在使用一个简单的队列实现,我正在尝试制作一个简单的程序,它有两个线程:第一个线程是队列上的队列事件,第二个线程处理它们。我使用互斥来避免同步问题。然而,我仍然经常(并非总是)遇到分段错误

请注意,我也使用
-D_可重入
选项构建代码。此外,如果仅从一个线程调用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;
                }
            }
        }
    }
}
以及处理功能:

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上识别故障
出列中

谢谢

一个小问题是:

if (!q->first) {
    *value = NULL;
    return 0;
}
(注意添加的星号)

主要的问题似乎是您没有在process\u events函数中为正在获取的
*分配内存

老实说,我会将该变量的类型更改为
struct input\u event*being\u fetched
,并将其地址传递给
dequeue
has\u item=dequeue(&my\u queue,&being\u fetched)
。这也将使您能够将ev作为一个单独的变量来处理。

一个小问题是:

if (!q->first) {
    *value = NULL;
    return 0;
}
(注意添加的星号)

主要的问题似乎是您没有在process\u events函数中为正在获取的
*分配内存


老实说,我会将该变量的类型更改为
struct input\u event*being\u fetched
,并将其地址传递给
dequeue
has\u item=dequeue(&my\u queue,&being\u fetched)
。这还可以让您将
ev
作为一个单独的变量去掉。

正如aix所说,您没有初始化*被获取。但我认为你最好用不同的定义:

struct input_event *being_fetched;
...
has_item = dequeue(&my_queue, &being_fetched);
...
ev = being_fetched;

然后确保您修复了aix提到的另一个bug,否则您将无法从函数中获取空指针。

正如aix所说,您没有初始化*被获取。但我认为你最好用不同的定义:

struct input_event *being_fetched;
...
has_item = dequeue(&my_queue, &being_fetched);
...
ev = being_fetched;


然后确保修复aix提到的另一个bug,否则就无法将空指针从函数中取出。

代码中的什么地方出现了SEGFULT?我知道内存泄漏,因为我没有删除创建的东西,但我认为这不是问题所在。在我的队列函数中。如果你认为可以的话,我也会发的。如果有人能帮忙,我会非常高兴的!代码中的什么地方出现了SEGFULT?我知道内存泄漏,因为我没有删除创建的内容,但我认为这不是问题所在。在我的排队函数中。如果你认为可以的话,我也会发的。如果有人能帮忙,我会非常高兴的!是的,对。还有一个事实,我应该在我的dequeue函数中释放一些mem。这并不重要,因为这也不能解释断层。我很困惑。我什么也没做,只是重新编译并运行了它,它没有任何问题……它(第二点)几乎肯定会有问题。您正在写入由未初始化指针指向的内存。如果不修复被获取的内存,将导致SEGFULT。是的,对于像我这样的Java开发人员来说,C是非常困难的:-D解决了它!我还添加了所有必要的
free
s,没有任何问题。谢谢是的,对。还有一个事实,我应该在我的dequeue函数中释放一些mem。这并不重要,因为这也不能解释断层。我很困惑。我什么也没做,只是重新编译并运行了它,它没有任何问题……它(第二点)几乎肯定会有问题。您正在写入由未初始化指针指向的内存。如果不修复被获取的内存,将导致SEGFULT。是的,对于像我这样的Java开发人员来说,C是非常困难的:-D解决了它!我还添加了所有必要的
free
s,没有任何问题。谢谢该死,甚至aix的退出速度也比我快+1为该值::-)是的。不过,非常感谢您的打扰:-)您真是太好了。该死,即使是aix的退出速度也比我的快+1为该值::-)是的。不过,非常感谢你的打扰:-)你真是太好了。