gpt4 book ai didi

c - 如何使队列线程安全

转载 作者:行者123 更新时间:2023-11-30 16:34:53 28 4
gpt4 key购买 nike

两个线程同时处理此队列可能会导致队列失败。您将如何做才能使并发访问正常工作?如果线程尝试从空队列中删除元素或将元素添加到满队列中,队列是否应该让线程等待?

#include <stdlib.h>

// circular array
typedef struct _queue {
int size;
int used;
int first;
void **data;
} _queue;

#include "queue.h"

queue q_create(int size) {
queue q = malloc(sizeof(_queue));

q->size = size;
q->used = 0;
q->first = 0;
q->data = malloc(size*sizeof(void *));

return q;
}

int q_elements(queue q) {
return q->used;
}

int q_insert(queue q, void *elem) {
if(q->size==q->used) return 0;

q->data[(q->first+q->used) % q->size] = elem;
q->used++;

return 1;
}

void *q_remove(queue q) {
void *res;
if(q->used==0) return NULL;

res=q->data[q->first];

q->first=(q->first+1) % q->size;
q->used--;

return res;
}

void q_destroy(queue q) {
free(q->data);
free(q);
}

该队列的目标是管理我正在开发的压缩工具的输入和输出。

最佳答案

线程安全意味着你必须隔离任何共享数据。这里你的共享数据是指向队列的指针。所以,一般来说,任何时候你对队列进行操作,你都需要保护队列并防止多个线程到达你的队列。同时排队。一个好的方法是实现条件变量。变量是在关键数据中锁定线程的开关。

我在这里看不到线程代码。因此,我们假设您有一个在队列中写入的线程。首先,您必须声明条件变量。

#include <pthread.h>


pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t w_condition = PTHREAD_COND_INITIALIZER;

que_state_t que_write_state = READY; //this is just an enum


void* writer_thread_v2(void* t)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
int i = 0;
while ( 1 )
{
pthread_mutex_lock(&mutex2);
while( que_write_state == NOT_READY )
{
pthread_cond_wait(&w_condition , &mutex2);
}
que_write_state = NOT_READY;
person_t* doe = NULL;
pthread_cleanup_push(clean_memory2, &doe);
doe = (person_t*) malloc(sizeof(person_t));

person_t static_person = random_person();
doe->age_bracket = static_person.age_bracket;
memcpy(doe->name , static_person.name , NAME_LENGTH);
push(the_queue , doe );
pthread_cleanup_pop(0);

que_write_state = READY;
pthread_mutex_unlock(&mutex2);
pthread_cond_signal(&w_condition);
i++;
}
pthread_exit(0);
}

此处线程进入 while 循环。

    pthread_mutex_lock(&mutex2);    //Here puts a lock on mutex    
while( que_write_state == NOT_READY ) //Here checks the enum
{
pthread_cond_wait(&w_condition , &mutex2);
}
que_write_state = NOT_READY; //Here puts the enum in not ready mode

现在,所有此类线程都将停止并等待,直到队列操作完成并释放互斥锁。这里就出现了一个很大的内存泄漏问题。如果一个线程创建了一个对象,并且在队列中添加数据之前取消了怎么办。这就是为什么代码中有

pthread_cleanup_push(clean_memory2, &doe);
{
inside here it mallocs the heap memory it is needed and adds data in
queue.If at any time the thread is cancelled clean_memory2() is called
which frees doe.
}
pthread_cleanup_pop(0);

pthread_cleanup_push 将在创建要存储的对象时保护您免受内存泄漏,并完成导入过程。Cleanup_push(幽灵 block )在清理开关处停止。插入 que 后,该线程将释放互斥体并向其余等待的线程发送信号。

    que_write_state = READY;   //here sets switch to ready mode
pthread_mutex_unlock(&mutex2); //unlocks mutex

pthread_cond_signal(&w_condition); //signal the next one.

谢谢。

关于c - 如何使队列线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49146897/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com