多個執行緒同時訪問臨界資源,產生二義性。
如何保證互斥鎖的原子訪問
互斥鎖使用過程
1.定義互斥鎖變數
pthread_mutex_t mutex1;
2.初始化互斥鎖:
int pthread_mutex_init(pthread_mutex_t * restrict mutex,const pthread_mutexattr_t*restrict attr)
第二個引數:互斥鎖屬性,一般設定為null
3.加鎖
以阻塞方式申請互斥鎖:(阻塞等待,不會向下執行)
extern int pthread_mutex_lock(pthread_mutex* _mutex)
以非阻塞方式申請互斥鎖:(直接返回,向下執行)
extern int pthread_mutex_trylock(pthread_mutex* _mutex)
4.釋放互斥鎖
釋放互斥鎖函式:
extern int pthread_mutex_unlock(pthread_mutex_t* _mutex)
5.銷毀互斥鎖
銷毀互斥鎖函式:
extern int pthread_mutex_destroy(pthread_mutex_t* _mutex)
注意:
死鎖的四個必要條件
避免死鎖
條件變數使用過程
1.定義條件變數
pthread_cond_t cond1;
2.初始化條件變數
int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
第二個引數:條件變數的屬性,一般為null
3.等待介面
//引數cond指定條件變數,引數mutex指定互斥量
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t * mutex);
//條件變數只保證同步【消費者和生產者】,互斥鎖保證(執行緒間)互斥【消費者和消費者,生產者和生產者】。
4.喚醒介面
//喚醒至少乙個阻塞在條件變數上的執行緒,也有可能會喚醒多個執行緒
int pthread_cond_signal(pthread_cond_t *cond);
//喚醒全部阻塞在條件變數上的執行緒
int pthread_cond_broadcast(pthread_cond_t *cond);
5.銷毀條件變數
//銷毀乙個條件變數
int pthread_cond_destroy(pthread_cond_t *cond);
舉例:
#include #include #include #define threadcount 4
//對於全域性變數g_noodle的取值,我們為了驗證執行緒之間進行同步,
//我們規定 0 是沒有面,1 是有麵的情況
int g_noodle = 0;
//定義互斥鎖資源
pthread_mutex_t g_mutex;
//吃飯的條件變數
pthread_cond_t g_cond;
//做飯的條件變數
pthread_cond_t g_makecond;
void* eatstart(void* arg)
g_noodle--;
printf("i am [%p], eat one noodle:[%d]\n", pthread_self(), g_noodle);
pthread_mutex_unlock(&g_mutex);
pthread_cond_signal(&g_makecond);
}return null;
} void* makestart(void* arg)
g_noodle++;
printf("i am [%p], i make one noodle:[%d]\n", pthread_self(), g_noodle);
pthread_mutex_unlock(&g_mutex);
pthread_cond_signal(&g_cond);
}return null;
} int main()
ret = pthread_create(&make_tid[i], null, makestart, null);
if(ret != 0)
}for(i = 0; i < threadcount; i++)
pthread_mutex_destroy(&g_mutex);
pthread_cond_destroy(&g_cond);
pthread_cond_destroy(&g_makecond);
return 0;
}
注意:
可以解耦合,消費者和生產者只通過佇列進行。
乙個執行緒安全佇列+兩種角色(消費者+生產者)+三種關係(消費者與消費者互斥,生產者與生產者互斥,消費者與生產者同步)
#include #include #include #include #define threadcount 4
class blockqueue
~blockqueue()
bool isfull()
return false;
}int pop(int* data)
*data = queue_.front();
queue_.pop();
pthread_mutex_unlock(&queuemutex_);
pthread_cond_signal(&producecond_);
return 0;
}int push(int& data)
queue_.push(data);
pthread_mutex_unlock(&queuemutex_);
pthread_cond_signal(&consumecond_);
return 0;
}private:
std::queuequeue_;
//定義的queue_的容量
size_t capacity_;
//互斥
pthread_mutex_t queuemutex_;
//同步
pthread_cond_t consumecond_;
pthread_cond_t producecond_;
};void* consumestart(void* arg)
return null;
} void* producestart(void* arg)
return null;
} int main()
ret = pthread_create(&pro_tid[i], null, producestart, (void*)bq);
if(ret != 0)
}for(i = 0; i < threadcount; i++)
delete bq;
return 0;
}
Linux 執行緒安全
概念 多個執行緒同時對臨界資源進行訪問,不會造成資料二義問題 實現 同步 互斥 同步 對臨界資源訪問的時序合理性 互斥 對臨界資源同一時間訪問的唯一性 執行緒間互斥的實現 互斥鎖mutex pthread mutex t mutex 定義互斥鎖變數 pthread mutex init pthrea...
Linux 執行緒安全
執行緒安全的實現 同步的實現 條件變數實現 條件變數 實現同步的思路向使用者提供兩個介面 乙個是負責讓執行緒陷入阻塞休眠的介面,乙個是負責喚醒執行緒 pcb等待佇列實質 通過條件判斷,什麼時候能夠使執行緒訪問臨界資源,若不能訪問就使得執行緒阻塞,若能夠訪問,就喚醒執行緒,實現執行緒對臨界資源訪問的合...
Linux 多執行緒執行緒安全
include include include include include include void fun void arg pthread exit null int main pthread join id,null exit 0 多執行緒 可以建立多少個執行緒 檢視所有後台大小限制 ul...