(1)線程同步
? ? ? ? ? ?1)線程同步:指一個線程發出某一個功能運行時,在運行還沒有結束的時候,該調用不返回。同時其它線程為保證數據的一致性,不能調用該功能。
? ? ? ? ? ?2)多個控制流共同操作一個共享資源的時候,都需要同步。
? ? ? ? ? ?3)數據混亂的原因:1》資源共享? 2》調度隨機? ?3》線程間缺乏必要的同步機制。
? ? ? ? ? ? ? ? ? ? ? 前兩點無法避免,只能從第三點開始優化。
(2)互斥量mutex
? ? ? ? ?1)linux中提供一把互斥鎖mutex(互斥量),每個線程都是提前對資源操作前都嘗試先加鎖,成功加鎖才能操作,操作結束后解鎖。
? ? ? ? ?2)同一個時刻,只能有一個線程持有該鎖。
? ? ? ? ?3)當線程A多某個全局變量加鎖訪問時,B在訪問時嘗試加鎖,失敗后,B阻塞。C線程不加鎖訪問全局變量,可以訪問,但是數據混亂,因此互斥鎖又被成為“建議鎖”(協同鎖),沒有強制限定。
(3)互斥量及相關函數:
? ? ? ? ? ? ? ? pthread_mutex_t類型,一個結構體,使用時可看做整數。函數成功返回0,失敗返回錯誤號。
? ? ? ? ? ? ? 1)pthread_mutex_intit:初始化一個互斥鎖(互斥量)? ? -->初值可看作1
? ? ? ? ? ? ? ? ? ? ? ?int pthread_mutex_init(pthread_mutex_t*restrict mutex,const pthread_mutexattr_t*restrict attr);
? ? ? ? ? ? ? ? ? ? 參數1;傳出參數,待初始化的互斥量。
? ? ? ? ? ? ? ? ? ? 參數2:看成互斥量屬性,出入參數,通常傳NULL,表示默認屬性(線程間共享)
? ? ? ? ? ? ? ? ? ? 靜態初始化: 使用宏初始化? pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
? ? ? ? ? ? ? ? ? ? 動態初始化:使用函數初始化。
? ? ? ? ? ? ? 2)pthread_mutex_destory:銷毀一個互斥鎖
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int? pthread_nutex_destory(pthread_mutex_t *mutex);
? ? ? ? ? ? ?3)pthread_mutex_lock:加鎖
? ? ? ? ? ? ? ? ? ? ? ? ? ?嘗試加鎖,加鎖不成功,則阻塞。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int? pthread_nutex_lock(pthread_mutex_t *mutex);
? ? ? ? ? ? ?4)pthread_mutex_unlock:解鎖
? ? ? ? ? ? ? ? ? ? ? ? ?喚醒阻塞所有線程。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???int? pthread_nutex_unlock(pthread_mutex_t *mutex);
? ? ? ? ? ? ?5)pthread_mutex_trylock:嘗試加鎖
? ? ? ? ? ? ? ? ? ? ? ? ?加鎖失敗后返回錯誤號,不阻塞。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??int? pthread_nutex_trylock(pthread_mutex_t *mutex);
(4)加鎖解鎖測試:不同線程實現不同的打印任務
? ? ? ?
? ? ? ? ?
? ? ? ? ? ?結論:在訪問共享資源時加鎖,訪問結束后解鎖,鎖的“粒度”越小越好
(5)死鎖
? ? ? ? ? ? ?1)同一個線程試圖多同一個互斥量加鎖兩次。
? ? ? ? ? ? ?2)線程1擁有A鎖請求B鎖;線程2擁有B鎖請求A鎖。
? ? ? ? ?