例如創建了N(如10個執行緒)個執行緒和一個大小為5的陣列。
場景: A執行緒寫下標為0的陣列項,B和C執行緒同時寫下標為1的陣列項
問題: 如何使得A執行緒寫下標0時,不影響B和C執行緒寫下標1,但B和C之間是互斥的。也就說如果使用鎖,如何做到只鎖定陣列某一項?
PS: 第一個提供可用demo加200分
uj5u.com熱心網友回復:
我感覺僅A單獨寫[0]記憶體不存在對該記憶體的競爭啊。不過大多數情況有讀就有寫。這時候就要考慮互斥的問題了。
int arr[10]
---------------------------------------------------
執行緒B:
...
lock(第二個元素的讀寫鎖)
寫arr[1]
unlock
...
---------------------------------------------------
執行緒C:
...
lock(第二個元素的讀寫鎖)
寫arr[1]
unlock
...
---------------------------------------------------
uj5u.com熱心網友回復:
弄一個大小為5的鎖陣列。uj5u.com熱心網友回復:
這樣會鎖住整個arr
uj5u.com熱心網友回復:
下標0 沒執行緒競爭不用管A執行緒寫下標0時本來就不影響B和C執行緒寫下標1
uj5u.com熱心網友回復:
我記憶中lock是鎖代碼的?我感覺應該沒記錯啊。只鎖住了兩個針對arr[1]的寫操作無法并行。
uj5u.com熱心網友回復:
下標0 沒執行緒競爭不用管
A執行緒寫下標0時本來就不影響B和C執行緒寫下標1
可能有X或Y執行緒也要訪問下標0,如果A鎖住了arr[0],這時候就影響了其他執行緒訪問arr其他下標
uj5u.com熱心網友回復:
和下標一一樣加鎖uj5u.com熱心網友回復:
和下標一一樣加鎖
但是寫訪問可能是一個方法,如:
void write(int index, int value)
{
lock();
arr[index] = value;
unlock();
}
這種寫法對所有呼叫該方法的執行緒都產生了互斥
uj5u.com熱心網友回復:
和下標一一樣加鎖
但是寫訪問可能是一個方法,如:
void write(int index, int value)
{
lock();
arr[index] = value;
unlock();
}
這種寫法對所有呼叫該方法的執行緒都產生了互斥
我想要的是對index級別的鎖
uj5u.com熱心網友回復:
和下標一一樣加鎖
但是寫訪問可能是一個方法,如:
void write(int index, int value)
{
lock();
arr[index] = value;
unlock();
}
這種寫法對所有呼叫該方法的執行緒都產生了互斥
我想要的是對index級別的鎖
別傻了
也沒有陣列級別的鎖
uj5u.com熱心網友回復:
lock();
b = index++;
arr[b] = value;
unlock();
uj5u.com熱心網友回復:
鎖是和鎖競爭 沒管鎖里面有什么資料能理解這一點嗎
所謂的 鎖資料是一個邏輯 而不是一個代碼物體
可能有X或Y執行緒也要訪問下標0,如果A鎖住了arr[0],這時候就影響了其他執行緒訪問arr其他下標
A鎖
A讀寫0下標
A解鎖
x y執行緒需要操作下標0
那就x y執行緒和A去競爭A鎖
其他執行緒 不操作A鎖 不會受到任何影響
uj5u.com熱心網友回復:
index級別的鎖,那就如2l說的一樣,弄一個一一對應的鎖。10個元素10把鎖這種咯~這種需求有些怪
uj5u.com熱心網友回復:
index級別的鎖,那就如2l說的一樣,弄一個一一對應的鎖。10個元素10把鎖這種咯~
這種需求有些怪
建議看看具體問題,然后再此衡量是否真的需要這樣做。畢竟鎖有些多。應該有更優的方式
uj5u.com熱心網友回復:
index級別的鎖,那就如2l說的一樣,弄一個一一對應的鎖。10個元素10把鎖這種咯~
這種需求有些怪
建議看看具體問題,然后再此衡量是否真的需要這樣做。畢竟鎖有些多。應該有更優的方式
一般用的都是直接鎖整個array。然后操作完了再開鎖。
公廁里那么多坑位這種實際問題也是一個房門一把鎖。
當然,優化一些的方式就是排號上廁所,通過信號量處理,前提是所有人不計較如廁的位置是哪個。
uj5u.com熱心網友回復:
弄一個大小為5的鎖陣列。
我感覺可能是原子陣列
uj5u.com熱心網友回復:
弄一個指標指向要加鎖的陣列位置, 給這個指標加鎖行不?int arr[] = {3, 2, 5 ,1 ,767 , 34};
int *temp = arr+2;
lock.lock();
printf("%d", *temp);
lock.unlock();
uj5u.com熱心網友回復:
#include <pthread.h>
pthread_mutex_t mutexes[5];
int data[5];
void* handle(void* arg){
while(1){
for (int i=0;i<5;i++) {
pthread_mutex_lock(&mutexes[i]);
data[i]=i;
pthread_mutex_unlock(&mutexes[i]);
}
}
}
int main() {
int i;
for(i=0;i<10;++i) pthread_mutex_init(&mutexes[i],NULL);
pthread_t p[10];
for(i=0;i<10;++i) pthread_create(&p[i],NULL,handle,NULL);
for(i=0;i<10;++i) pthread_join(p[i],NULL);
return 0;
}
uj5u.com熱心網友回復:
現在陣列小可能還行,假如陣列很大就要配陣列大小一樣多的鎖uj5u.com熱心網友回復:
這個不行,執行緒x先來拿到資料,執行緒y后來也拿到資料,剛好x執行緒休眠/掛起/時間片到,結果y執行緒先執行完uj5u.com熱心網友回復:
#include <pthread.h>
pthread_mutex_t mutexes[5];
int data[5];
void* handle(void* arg){
while(1){
for (int i=0;i<5;i++) {
pthread_mutex_lock(&mutexes[i]);
data[i]=i;
pthread_mutex_unlock(&mutexes[i]);
}
}
}
int main() {
int i;
for(i=0;i<10;++i) pthread_mutex_init(&mutexes[i],NULL);
pthread_t p[10];
for(i=0;i<10;++i) pthread_create(&p[i],NULL,handle,NULL);
for(i=0;i<10;++i) pthread_join(p[i],NULL);
return 0;
}
這個就是陣列有多大,鎖就多少。是實作了,但是實際中陣列可能很大
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/169718.html
標籤:C++ 語言
