- 互斥鎖:鏈表用在多線程中保證順序,多個線程會操作同一個鏈表,互斥鎖保證多線程操作的安全,互斥鎖分情況使用,鏈表并不一定需要互斥鎖。
typedef struct SDL_mutex {
pthread_mutex_t id;
} SDL_mutex;
typedef struct SDL_cond {
pthread_cond_t id;
} SDL_cond;
SDL_mutex *SDL_CreateMutex(void)
{
SDL_mutex *mutex;
mutex = (SDL_mutex *) mallocz(sizeof(SDL_mutex));
if (!mutex)
return NULL;
if (pthread_mutex_init(&mutex->id, NULL) != 0) {
free(mutex);
return NULL;
}
return mutex;
}
void SDL_DestroyMutex(SDL_mutex *mutex)
{
if (mutex) {
pthread_mutex_destroy(&mutex->id);
free(mutex);
}
}
void SDL_DestroyMutexP(SDL_mutex **mutex)
{
if (mutex) {
SDL_DestroyMutex(*mutex);
*mutex = NULL;
}
}
int SDL_LockMutex(SDL_mutex *mutex)
{
assert(mutex);
if (!mutex)
return -1;
return pthread_mutex_lock(&mutex->id);
}
int SDL_UnlockMutex(SDL_mutex *mutex)
{
assert(mutex);
if (!mutex)
return -1;
return pthread_mutex_unlock(&mutex->id);
}
SDL_cond *SDL_CreateCond(void)
{
SDL_cond *cond;
cond = (SDL_cond *) mallocz(sizeof(SDL_cond));
if (!cond)
return NULL;
if (pthread_cond_init(&cond->id, NULL) != 0) {
free(cond);
return NULL;
}
return cond;
}
void SDL_DestroyCond(SDL_cond *cond)
{
if (cond) {
pthread_cond_destroy(&cond->id);
free(cond);
}
}
void SDL_DestroyCondP(SDL_cond **cond)
{
if (cond) {
SDL_DestroyCond(*cond);
*cond = NULL;
}
}
int SDL_CondSignal(SDL_cond *cond)
{
assert(cond);
if (!cond)
return -1;
return pthread_cond_signal(&cond->id);
}
typedef struct Queue{
node *phead, *first_node, *last_node;
int count;
SDL_mutex *mutex;
SDL_mutex *ex_mutex;
SDL_cond *cond;
}queue;
typedef struct queue_node {
struct queue_node* prev;
struct queue_node* next;
void *para;
} node;
/**
雙向鏈表 創建一個節點
@param para 要保存到鏈表的內容
@return 返回創建的這個節點
*/
static node* create_node(void *para)
{
node *pnode = NULL;
pnode = (node *) malloc(sizeof(node));
if (pnode)
{
pnode->prev = pnode->next = pnode;
pnode->para = para;
}
return pnode;
}
/**
創建鏈表的phead
@param q 鏈表
@return success return 0, fail return -1
*/
int create_queue(queue *q)
{
q->phead = create_node(NULL);
if (!q->phead)
return -1;
return 0;
}
/**
初始化一個鏈表
@param q 鏈表
@return 鏈表的頭
*/
static int queue_init(queue *q)
{
memset(q, 0, sizeof(queue));
q->phead = NULL;
q->last_node = NULL;
q->first_node = NULL;
q->count = 0;
q->mutex = SDL_CreateMutex();
if (!q->mutex)
{
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
q->ex_mutex = SDL_CreateMutex();
if (!q->ex_mutex)
{
av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
q->cond = SDL_CreateCond();
if (!q->cond)
{
av_log(NULL, AV_LOG_FATAL, "SDL_CreateCond(): %s\n", SDL_GetError());
return AVERROR(ENOMEM);
}
return create_queue(q);
}
/**
判斷鏈表是否為空
@param q 鏈表
@return 空:return 1,不是空:return 0
*/
int queue_is_empty(queue *q)
{
return q->count == 0;
}
/**
獲取鏈表長度
@param q 鏈表
@return 鏈表中元素的個數
*/
int queue_size(queue *q)
{
return q->count;
}
/**
根據index獲取鏈表的節點
@param q 鏈表
@param index 鏈表元素下標
@return 該下標的鏈表元素節點。
*/
static node* get_node(queue *q,int index)
{
if (index < 0 || index >= q->count)
return NULL;
if (index <= (q->count / 2))
{
int i = 0;
node *pnode = q->phead->next;
while ((i++) < index)
pnode = pnode->next;
return pnode;
}
int j = 0;
int rindex = q->count - index - 1;
node *rnode = q->phead->prev;
while ((j++) < rindex)
rnode = rnode->prev;
return rnode;
}
/**
根據index獲取改鏈表節點里面的存儲內容
@param q 鏈表
@param index 鏈表節點下標
@return 該下標元素節點中存儲的內容
*/
void* queue_get(queue *q,int index)
{
SDL_LockMutex(q->mutex);
node *pindex = get_node(q,index);
if (!pindex)
{
SDL_UnlockMutex(q->mutex);
return NULL;
}
SDL_UnlockMutex(q->mutex);
return pindex->para;
}
/**
獲取該鏈表第一個節點存儲的內容
@param q 鏈表
@return 該鏈表的某個節點內容
*/
void* queue_get_first(queue *q)
{
return queue_get(q,0);
}
/**
獲取該鏈表最后一個節點存儲的內容
@param q 鏈表
@return 該鏈表的某個節點內容
*/
void* queue_get_last(queue *q)
{
return queue_get(q,q->count - 1);
}
/**
存儲一個元素到鏈表
@param q 要存儲到的鏈表
@param para 要存儲的內容
@return success return 0 ,fail return -1
*/
int queue_append_last(queue *q,void *para)
{
SDL_LockMutex(q->mutex);
node *pnode = create_node(para);
if (!pnode)
{
SDL_UnlockMutex(q->mutex);
return -1;
}
pnode->next = q->phead;
pnode->prev = q->phead->prev;
q->phead->prev->next = pnode;
q->phead->prev = pnode;
q->last_node = pnode;
q->count++;
SDL_UnlockMutex(q->mutex);
return 0;
}
/**
根據index 刪除鏈表的元素節點
@param q 鏈表
@param index 要刪除的節點下標
@return success return 0 ,fail return -1
*/
int queue_delete(queue *q,int index)
{
SDL_LockMutex(q->mutex);
node *pindex = get_node(q,index);
if (!pindex)
{
SDL_UnlockMutex(q->mutex);
return -1;
}
pindex->next->prev = pindex->prev;
pindex->prev->next = pindex->next;
free(pindex);
q->count--;
SDL_UnlockMutex(q->mutex);
return 0;
}
/**
刪除該鏈表第一個節點
@param q 鏈表
@return success return 0 ,fail return -1
*/
int queue_delete_first(queue *q)
{
return queue_delete(q,0);
}
/**
刪除該鏈表最后一個節點
@param q 鏈表
@return success return 0 ,fail return -1
*/
int queue_delete_last(queue *q)
{
return queue_delete(q, q->count - 1);
}
/**
銷毀鏈表
@param q 鏈表
@return success return 0 ,fail return -1
*/
int destroy_queue(queue *q)
{
SDL_LockMutex(q->mutex);
if (!q->phead)
{
SDL_UnlockMutex(q->mutex);
return -1;
}
node *pnode = q->phead->next;
node *ptmp = NULL;
while (pnode != q->phead)
{
ptmp = pnode;
pnode = pnode->next;
free(ptmp);
}
free(q->phead);
q->phead = NULL;
q->last_node = NULL;
q->first_node = NULL;
q->count = 0;
SDL_UnlockMutex(q->mutex);
SDL_DestroyMutex(q->mutex);
SDL_DestroyCond(q->cond);
return 0;
}
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。