2012-02-02 85 views
1

這個問題是一個可能的子問題,這concurrent access and free of a data structure併發訪問,並免費堆對象

另一個問題是開放式的設計,這是一個更具體。

struct ds 
{ 
    int x,y,z;  
    pthread_mutex_t mutex; 
}; 

我需要一個確定性的解決方案,通過它可以同時訪問1個ds類型的對象並釋放它。

約束:

  1. 您可以互斥的指針,但不能把它拿出來的對象。

真正的問題:

免費不能做持有鎖,因爲,再由鎖佔用的內存也丟失。

我已經閱讀了很多關於參考計數的論文和文章,但是他們中的每一個都在ds之外保持鎖定。我想要一個解決方案,我可以在ds內部鎖定或引用鎖。

+0

我想問題歸結爲確保在免費時沒有對象的外部引用。所以如果外部引用是一個指針,我們需要在ds之外另一個鎖來確保對象沒有消失。這就是爲什麼他們發明了boost的shared_ptr。 – Saurabh 2012-02-03 13:13:02

回答

1

既然你說「的互斥體可以是一個指針」,你可以做這樣的事情:

struct ds { pthread_mutex_t * mutex; /* ... */ }; 

struct ds * create_ds() 
{ 
    struct ds * p = calloc(1, sizeof(struct ds)); 
    pthread_mutex_t * q = malloc(sizeof(pthread_mutex_t)); 
    pthread_mutex_init(q, NULL); 
    ds->mutex = q; 
    return p; 
} 

void free_ds(struct ds * p) 
{ 
    pthread_mutex_t * q = p->mutex; 
    pthread_mutex_lock(q); 
    free(p); 
    pthread_mutex_unlock(q); 
    pthread_mutex_destroy(q); 
    free(q); 
} 

在我看來,雖然,銷燬的對象是不是真的東西,適合併發訪問/同步成語。如果你摧毀了一些東西,它就不再存在了,所以所有線程都受到這個影響。線程應該如何知道給定的ds指針是否仍然指向有效的東西?

相反,你應該有一個收集ds對象的地方,並插入/刪除訪問該集合應該有它自己的,獨立的,收藏級的互斥。每當一個線程想要獲得對集合中某個對象的引用時,它應該在一個互斥體的守護之下這樣做,並且該集合應該知道誰正在持有引用。

+0

'free_ds'中的代碼仍然是不安全的:如果互斥體破壞是在另一個具有相同'struct ds'實例的地址的線程嘗試訪問它時完成的呢? – 2012-02-02 21:03:21

+0

@AlexeyKukanov:正如我在最後兩段中所說的,我不認爲你可以使用一個元素互斥來防止* container *突變,所以釋放一個元素真的應該由其他人守護,而不是元素本身。 – 2012-02-02 21:43:44

+0

@KerrekSB我有同樣的觀點,無論互斥體或其指針是否在數據結構中,這個問題都是無法解決的。我認爲可能會有一些解決方案使用原始問題中某人提出的原子CAS指令/危險指針。 – Saurabh 2012-02-03 06:27:02