【发布时间】:2014-12-21 00:54:49
【问题描述】:
尝试使用引用计数在纯 C 中的线程之间传递结构。我有 pthreads 和 gcc atomics 可用。我可以让它工作,但我正在寻找防弹。
一开始,我使用了结构本身拥有的 pthread 互斥锁:
struct item {
int ref;
pthread_mutex_t mutex;
};
void ref(struct item *item) {
pthread_mutex_lock(&item->mutex);
item->ref++;
pthread_mutex_unlock(&item->mutex);
}
void unref(struct item *item) {
pthread_mutex_lock(&item->mutex);
item->ref--;
pthread_mutex_unlock(&item->mutex);
if (item->ref <= 0)
free(item);
}
struct item *alloc_item(void) {
struct item *item = calloc(1, sizeof(*item));
return item;
}
但是,意识到互斥锁不应该归项目所有:
static pthread_mutex_t mutex;
struct item {
int ref;
};
void ref(struct item *item) {
pthread_mutex_lock(&mutex);
item->ref++;
pthread_mutex_unlock(&mutex);
}
void unref(struct item *item) {
pthread_mutex_lock(&mutex);
item->ref--;
if (item->ref <= 0)
free(item);
pthread_mutex_unlock(&mutex);
}
struct item *alloc_item(void) {
struct item *item = calloc(1, sizeof(*item));
return item;
}
然后,进一步实现的指针是按值传递的,所以我现在有了:
static pthread_mutex_t mutex;
struct item {
int ref;
};
void ref(struct item **item) {
pthread_mutex_lock(&mutex);
if (item != NULL) {
if (*item != NULL) {
(*item)->ref++;
}
}
pthread_mutex_unlock(&mutex);
}
void unref(struct item **item) {
pthread_mutex_lock(&mutex);
if (item != NULL) {
if (*item != NULL) {
(*item)->ref--;
if ((*item)->ref == 0) {
free((*item));
*item = NULL;
}
}
}
pthread_mutex_unlock(&mutex);
}
struct item *alloc_item(void) {
struct item *item = calloc(1, sizeof(*item));
if (item != NULL)
item->ref = 1;
return item;
}
这里有什么逻辑错误吗?谢谢!
【问题讨论】:
-
“我可以让它工作,但我正在寻找防弹。” - ???为什么不使用原子?
-
这里不需要双重间接:
void ref(struct item **item) -
那么你到底为什么要使用指针指向指针呢?
-
int ref;也应该是未签名的。 -
@KarolyHorvath 随意发布使用原子的版本。