1. 程式人生 > >Linux程式設計學習筆記----多執行緒程式設計執行緒同步機制之互斥量(鎖)與讀寫鎖

Linux程式設計學習筆記----多執行緒程式設計執行緒同步機制之互斥量(鎖)與讀寫鎖

互斥鎖通訊機制

基本原理

互斥鎖以排他方式防止共享資料被併發訪問,互斥鎖是一個二元變數,狀態為開(0)和關(1),將某個共享資源與某個互斥鎖邏輯上繫結之後,對該資源的訪問操作如下:

(1)在訪問該資源之前需要首先申請互斥鎖,如果鎖處於開狀態,則申請得到鎖並立即上鎖(關),防止其他程序訪問資源,如果鎖處於關,則預設阻塞等待.

(2)只有鎖定該互斥鎖的程序才能釋放該互斥鎖.

互斥量型別宣告為pthread_mutex_t資料型別,在<bits/pthreadtypes.h>中有具體的定義。

互斥量初始化和銷燬

在使用互斥鎖之前需要定義互斥鎖(全域性變數),定義程式碼:

pthread_mutex lock;
/* Initialize a mutex.  */
int pthread_mutex_init (pthread_mutex_t *__mutex,\      // 指向要初始化的互斥鎖的指標
                        __const pthread_mutexattr_t *__mutexattr); // 指向互斥鎖屬性物件的指標,設null為預設屬性

/* Destroy a mutex.  */
int pthread_mutex_destroy (pthread_mutex_t *__mutex);

上面兩個函式分別由於互斥量的初始化和銷燬。

如果互斥量是靜態分配的,可以通過常量進行初始化,如下:

#define PTHREAD_MUTEX_INITIALIZER {{0, }}  // 系統定義的,無需宣告
pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;

當然也可以通過pthread_mutex_init()進行初始化。對於動態分配的互斥量由於不能直接賦值進行初始化就只能採用這種方式進行初始化,pthread_mutex_init()的第二個引數是互斥量的屬性,如果採用預設的屬性設定,可以傳入NULL。

當不在需要使用互斥量時,需要呼叫pthread_mutex_destroy()銷燬互斥量所佔用的資源。

互斥量的屬性設定

/* 初始化互斥量屬性物件 */
int pthread_mutexattr_init (pthread_mutexattr_t *__attr);

/* 銷燬互斥量屬性物件  */
int pthread_mutexattr_destroy (pthread_mutexattr_t *__attr);

/* 獲取互斥量屬性物件在程序間共享與否的標誌 */
int pthread_mutexattr_getpshared (__const pthread_mutexattr_t *__restrict __attr, \
                                   int *__restrict __pshared);

/* 設定互斥量屬性物件,標識在程序間共享與否 */
int pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr, int __pshared);

互斥量在初始化的時候pthread_mutex_init的第二個引數是互斥量的屬性,如果為NULL空指標,那麼就使用預設屬性。

互斥量屬性的資料型別為pthread_mutexattr_t,它的初始化和銷燬和互斥量類似。一旦互斥量屬性物件被初始化後,就可以通過呼叫不同的函式啟用或禁止特定的屬性。這裡列出了一個設定特定屬性的函式:pthread_mutexattr_setpshared,可以用於指定互斥量在不同程序間共享,這樣可以通過互斥量來同步不同的程序,當然前提是該互斥量位於程序間的共享記憶體區。

pthread_mutexattr_setpshared()函式的第二個引數__pshared用於設定是否程序間共享,其值可以是PTHREAD_PROCESS_PRIVATEPTHREAD_PROCESS_SHARED,後者是設定程序間共享。

下面是使互斥量可以在程序間共享的大致過程:

pthread_mutex_t *pSharedMutex;  //指向共享記憶體區的互斥量
pthread_mutexattr_t mutexAttr;  //互斥量屬性

pSharedMutex = /*一個指向共享記憶體區的指標*/;

pthread_mutexattr_init(&mutexAttr);
pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(pSharedMutex, &mutexAttr);

互斥量的申請使用

/* Try locking a mutex.  */
int pthread_mutex_trylock (pthread_mutex_t *__mutex);

/* Lock a mutex.  */
int pthread_mutex_lock (pthread_mutex_t *__mutex);

/* Unlock a mutex.  */
int pthread_mutex_unlock (pthread_mutex_t *__mutex);
這幾個函式都很簡單,通過pthread_mutex_lock()函式獲得訪問共享資源的許可權,如果已經有其他執行緒鎖住互斥量,那麼該函式會是執行緒阻塞指定該互斥量解鎖為止。 pthread_mutex_trylock()是對應的非阻塞函式,如果互斥量已被佔用,它會返回一個EBUSY錯誤。訪問完共享資源後,一定要通過pthread_mutex_unlock() 函式,釋放佔用的互斥量。允許其他執行緒訪問該資源。

這裡要強調的是:互斥量是用於上鎖的,不能用於等待。

簡單說就是,互斥量的使用流程應該是:執行緒佔用互斥量,然後訪問共享資源,最後釋放互斥量。而不應該是:執行緒佔用互斥量,然後判斷資源是否可用,如果不可用,釋放互斥量,然後重複上述過程。這種行為稱為輪轉或輪詢,是一種浪費CPU時間的行為。

應用示例

下面的程式使用了兩個同進程的執行緒,一個執行緒負責從標準裝置讀入資料儲存在共享資料區,另一個負責將讀入的資料輸出到標準裝置.其實是一個生產者消費者的變形.

  1. 處理輸入操作的執行緒在接受使用者資訊的時候必須互斥使用該資源,不能被打斷,阻塞其他執行緒的進行
  2. 輸出執行緒也不能被打斷,需要先鎖定互斥鎖,操作完成後釋放,
  3. 程式結束,銷燬互斥鎖.

程式碼如下:

/*************************************************************************
> File Name: pthread_exp.c
> Author:SuooL 
> Mail:[email protected] || [email protected]
> Website:http://blog.csdn.net/suool | http://suool.net
> Created Time: 2014年08月15日 星期三 08時42分45秒
> Description: 
************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>

void *thread_function(void *arg);

pthread_mutex_t work_mutex;     // 定義全域性互斥鎖物件

#define WORK_SIZE 1024          
char work_area[WORK_SIZE];      // 全域性共享資料區
int time_to_exit = 0;           // 標誌變數

// main函式
int main(int argc,char *argv[]) 
{
    int res;
    pthread_t a_thread;           // 執行緒
    void *thread_result;
    res = pthread_mutex_init(&work_mutex, NULL); //init mutex 初始化互斥鎖
    if (res != 0) 
    {
        perror("Mutex initialization failed");
        exit(EXIT_FAILURE);
    }
    res = pthread_create(&a_thread, NULL, thread_function, NULL);//create new thread
    if (res != 0) 
    {
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }
    pthread_mutex_lock(&work_mutex);			//lock the mutex,before get the input
    printf("Input some text. Enter 'end' to finish\n");
    while(!time_to_exit) 
    {
        fgets(work_area, WORK_SIZE, stdin);		//get a string from stdin
        pthread_mutex_unlock(&work_mutex);		//unlock the mutex
        while(1) 
        {
            pthread_mutex_lock(&work_mutex);	//lock the mutex
            if (work_area[0] != '\0')              // check out if the info input has been output
            {
                pthread_mutex_unlock(&work_mutex);	//unlock the mutex
                sleep(1);
            }
            else                                // if has been output, break and goto next iput
            {
                break;
            }
        }
    }
    pthread_mutex_unlock(&work_mutex);          // unlock the mutex 
    printf("\nWaiting for thread to finish...\n");
    res = pthread_join(a_thread, &thread_result);    // wait for the other pthread end
    if (res != 0) 
    {
        perror("Thread join failed");
        exit(EXIT_FAILURE);
    }
    printf("Thread joined\n");
    pthread_mutex_destroy(&work_mutex);         // destory the mutex
    exit(EXIT_SUCCESS);
}

// the pthread run function
void *thread_function(void *arg) 
{
    sleep(1);
    pthread_mutex_lock(&work_mutex);  // lock the mutex 搶佔資源
    while(strncmp("end", work_area, 3) != 0)   // 判斷是否為結束資訊
    {
        printf("You input %d characters\n", strlen(work_area) -1); // 輸出輸入資訊
        printf("the characters is %s",work_area);
        work_area[0] = '\0';         // 設定資料區,表示輸入已被輸出
        pthread_mutex_unlock(&work_mutex);   // 解鎖
        sleep(1);
        pthread_mutex_lock(&work_mutex);     // 上鎖
        while (work_area[0] == '\0' )        // 判斷是否被輸出
        {                 // 如果是\0則沒有輸入,等待主程序輸入
         pthread_mutex_unlock(&work_mutex); // 解鎖
         sleep(1);                            // 等待
         pthread_mutex_lock(&work_mutex);   // 上鎖,再次檢測
        }
    }
    time_to_exit = 1;             // 設定主執行緒退出訊號
    work_area[0] = '\0';           // 標誌輸出
    pthread_mutex_unlock(&work_mutex);    // 世界所
    pthread_exit(0);           // 執行緒退出
}

執行結果:

讀寫鎖通訊機制

讀寫鎖和互斥量(互斥鎖)很類似,是另一種執行緒同步機制,但不屬於POSIX標準,可以用來同步同一程序中的各個執行緒。當然如果一個讀寫鎖存放在多個程序共享的某個記憶體區中,那麼還可以用來進行程序間的同步.

因為對資料的讀寫應用中,很多情況都是大量的讀操作,而較少有寫操作,例如對資料庫的訪問等,顯然這樣使用互斥鎖會很影響效率,為了滿足這樣的需求,POSIX線提供了讀寫鎖機制.模式如下:

  1. 如果當前程序讀資料,其他的程序也可以進行讀操作,但不能寫操作
  2. 如果當前程序寫資料,則所有其它程序阻塞等待

和互斥量不同的是:互斥量會把試圖進入已保護的臨界區的執行緒都阻塞;然而讀寫鎖會視當前進入臨界區的執行緒和請求進入臨界區的執行緒的屬性來判斷是否允許執行緒進入。

相對互斥量只有加鎖和不加鎖兩種狀態,讀寫鎖有三種狀態:讀模式下的加鎖,寫模式下的加鎖,不加鎖

讀寫鎖的使用規則:

  • 只要沒有寫模式下的加鎖,任意執行緒都可以進行讀模式下的加鎖;
  • 只有讀寫鎖處於不加鎖狀態時,才能進行寫模式下的加鎖;

讀寫鎖也稱為共享-獨佔(shared-exclusive)鎖,當讀寫鎖以讀模式加鎖時,它是以共享模式鎖住,當以寫模式加鎖時,它是以獨佔模式鎖住。讀寫鎖非常適合讀資料的頻率遠大於寫資料的頻率從的應用中。這樣可以在任何時刻執行多個讀執行緒併發的執行,給程式帶來了更高的併發度。

定義程式碼如下:

pthread_rwlock_t ralock;

初始化和銷燬讀寫鎖

/* Initialize read-write lock  */
 int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,  // 指向要初始化的讀寫鎖指標
                                __const pthread_rwlockattr_t *__restrict __attr); // 指向屬性物件的指標

/* Destroy read-write lock */
extern int pthread_rwlock_destroy (pthread_rwlock_t *__rwlock); //返回值:成功返回0,否則返回錯誤程式碼

上面兩個函式分別由於讀寫鎖的初始化和銷燬。和互斥量,條件變數一樣,如果讀寫鎖是靜態分配的,可以通過常量進行初始化,如下:

<span style="font-size:12px;">pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;</span>

也可以通過pthread_rwlock_init()進行初始化。對於動態分配的讀寫鎖由於不能直接賦值進行初始化,只能通過這種方式進行初始化。pthread_rwlock_init()第二個引數是讀寫鎖的屬性,如果採用預設屬性,可以傳入空指標NULL

那麼當不在需要使用時及釋放(自動或者手動)讀寫鎖佔用的記憶體之前,需要呼叫pthread_rwlock_destroy()進行銷燬讀寫鎖佔用的資源。

讀寫鎖的屬性設定

/* 初始化讀寫鎖屬性物件 */
int pthread_rwlockattr_init (pthread_rwlockattr_t *__attr);

/* 銷燬讀寫鎖屬性物件 */
int pthread_rwlockattr_destroy (pthread_rwlockattr_t *__attr);

/* 獲取讀寫鎖屬性物件在程序間共享與否的標識*/
int pthread_rwlockattr_getpshared (__const pthread_rwlockattr_t * __restrict __attr,
                                          int *__restrict __pshared);

/* 設定讀寫鎖屬性物件,標識在程序間共享與否  */
int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *__attr, int __pshared);

                                                    返回值:成功返回0,否則返回錯誤程式碼
這個屬性設定和互斥量的基本一樣,具體可以參考上面的互斥量的設定互斥量的屬性設定

讀寫鎖的申請使用

/* 讀模式下加鎖  */
int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);

/* 非阻塞的讀模式下加鎖  */
int pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock);

# ifdef __USE_XOPEN2K
/*  限時等待的讀模式加鎖 */
int pthread_rwlock_timedrdlock (pthread_rwlock_t *__restrict __rwlock,
                                       __const struct timespec *__restrict __abstime);
# endif

/* 寫模式下加鎖  */
int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock);

/* 非阻塞的寫模式下加鎖 */
int pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock);

# ifdef __USE_XOPEN2K
/* 限時等待的寫模式加鎖 */
int pthread_rwlock_timedwrlock (pthread_rwlock_t *__restrict __rwlock,
                                       __const struct timespec *__restrict __abstime);
# endif

/* 解鎖 */
int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock);

                                                   返回值:成功返回0,否則返回錯誤程式碼
(1)pthread_rwlock_rdlock()系列函式

pthread_rwlock_rdlock()用於以讀模式即共享模式獲取讀寫鎖,如果讀寫鎖已經被某個執行緒以寫模式佔用,那麼呼叫執行緒就被阻塞。在實現讀寫鎖的時候可以對共享模式下鎖的數量進行限制(目前不知如何限制)。

pthread_rwlock_tryrdlock()和pthread_rwlock_rdlock()的唯一區別就是,在無法獲取讀寫鎖的時候,呼叫執行緒不會阻塞,會立即返回,並返回錯誤程式碼EBUSY。

pthread_rwlock_timedrdlock()是限時等待讀模式加鎖,時間引數struct timespec * __restrict __abstime也是絕對時間,和條件變數的pthread_cond_timedwait()使用基本一致,具體可以參考pthread_cond_timedwait()

(2)pthread_rwlock_wrlock()系列函式

pthread_rwlock_wrlock()用於寫模式即獨佔模式獲取讀寫鎖,如果讀寫鎖已經被其他執行緒佔用,不論是以共享模式還是獨佔模式佔用,呼叫執行緒都會進入阻塞狀態。

pthread_rwlock_trywrlock()在無法獲取讀寫鎖的時候,呼叫執行緒不會進入睡眠,會立即返回,並返回錯誤程式碼EBUSY。

pthread_rwlock_timedwrlock()是限時等待寫模式加鎖,也和條件變數的pthread_cond_timedwait()使用基本一致,具體可以參考pthread_cond_timedwait()

(3)pthread_rwlock_unlock()

無論以共享模式還是獨佔模式獲得的讀寫鎖,都可以通過呼叫pthread_rwlock_unlock()函式進行釋放該讀寫鎖。

讀寫鎖應用

下面的程式使用讀寫鎖實現4個執行緒讀寫一段資料.

其中兩個執行緒讀資料,兩個執行緒寫資料.

從結果看出,任意程序寫資料的時候,將阻塞所有其他程序的操作,但在某一程序讀資料的時候,其他程序仍然可以讀得資料.

編譯執行結果如下:

程式碼如下:

/*************************************************************************
> File Name: pthread_rwlock_exp.c
> Author:SuooL 
> Mail:[email protected] || [email protected]
> Website:http://blog.csdn.net/suool | http://suool.net
> Created Time: 2014年08月15日 星期三 09時20分45秒
> Description: 
************************************************************************/
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bits/pthreadtypes.h>

static pthread_rwlock_t rwlock;     // 讀寫鎖物件

#define WORK_SIZE 1024
char work_area[WORK_SIZE];          // 全域性共享資料區
int time_to_exit;                   // 標誌變數

// 子執行緒執行的函式宣告
void *thread_function_read_o(void *arg);
void *thread_function_read_t(void *arg);
void *thread_function_write_o(void *arg);
void *thread_function_write_t(void *arg);

// main 函式
int main(int argc,char *argv[]) 
{
    int res;
    pthread_t a_thread,b_thread,c_thread,d_thread;  // 執行緒定義
    void *thread_result;            // 指標定義

    res=pthread_rwlock_init(&rwlock,NULL);         // 讀寫鎖定義
    if (res != 0) 
    {
        perror("rwlock initialization failed");
        exit(EXIT_FAILURE);
    }
    // 建立子執行緒
    res = pthread_create(&a_thread, NULL, thread_function_read_o, NULL);//create new thread
    if (res != 0) 
    {
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }

    res = pthread_create(&b_thread, NULL, thread_function_read_t, NULL);//create new thread
    if (res != 0) 
    {
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }
    res = pthread_create(&c_thread, NULL, thread_function_write_o, NULL);//create new thread
    if (res != 0)
    {
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }
    res = pthread_create(&d_thread, NULL, thread_function_write_t, NULL);//create new thread
    if (res != 0)
    {
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }
    // 執行緒等待
    res = pthread_join(a_thread, &thread_result);			
    if (res != 0) 
    {
        perror("Thread join failed");
        exit(EXIT_FAILURE);
    }
    res = pthread_join(b_thread, &thread_result);			
    if (res != 0) 
    {
        perror("Thread join failed");
        exit(EXIT_FAILURE);
    }
    res = pthread_join(c_thread, &thread_result);			
if (res != 0) 
{
    perror("Thread join failed");
    exit(EXIT_FAILURE);
}
res = pthread_join(d_thread, &thread_result);			
if (res != 0) 
{
    perror("Thread join failed");
    exit(EXIT_FAILURE);
}
// 讀寫鎖銷燬
pthread_rwlock_destroy(&rwlock);				
exit(EXIT_SUCCESS);
}

void *thread_function_read_o(void *arg)            // 讀執行緒one
{
    printf("thread read one try to get lock\n");	

    pthread_rwlock_rdlock(&rwlock);          // 獲取讀寫鎖
    while(strncmp("end", work_area, 3) != 0)    // 判斷是否為輸入結束符
    {
        printf("this is thread read one.\n");   // 輸出資訊
        printf("the characters is %s",work_area);	
        pthread_rwlock_unlock(&rwlock);		// 解鎖	
        sleep(2);
        pthread_rwlock_rdlock(&rwlock);			// 獲取所
        while (work_area[0] == '\0' ) 		  // 檢視資料區開頭是否為\0
        {
            pthread_rwlock_unlock(&rwlock);	 // 解鎖
            sleep(2);                        // 等待
            pthread_rwlock_rdlock(&rwlock);  // 獲取鎖,再次檢視
        }
    }	
    pthread_rwlock_unlock(&rwlock);	   // 解鎖
    time_to_exit=1;  // 設定退出訊號
    pthread_exit(0);  // 執行緒退出
}

 void *thread_function_read_t(void *arg)              // 讀執行緒two,同one
 {
     printf("thread read one try to get lock\n");
     pthread_rwlock_rdlock(&rwlock);
     while(strncmp("end", work_area, 3) != 0) 
     {
         printf("this is thread read two.\n");
         printf("the characters is %s\n",work_area);	
         pthread_rwlock_unlock(&rwlock);			
         sleep(5);
         pthread_rwlock_rdlock(&rwlock);			
         while (work_area[0] == '\0' ) 		 
         {				
             pthread_rwlock_unlock(&rwlock);	
             sleep(5);
             pthread_rwlock_rdlock(&rwlock);	
         }
     }
     pthread_rwlock_unlock(&rwlock);	
     time_to_exit=1;
     pthread_exit(0);
 }

void *thread_function_write_o(void *arg)        // 寫執行緒one
{
    printf("this is write thread one try to get lock\n"); // 輸出提示資訊
    while(!time_to_exit)               // 是否退出
    {
        pthread_rwlock_wrlock(&rwlock);       // 獲取讀寫鎖
        printf("this is write thread one.\nInput some text. Enter 'end' to finish\n");
        fgets(work_area, WORK_SIZE, stdin); // 獲取標準輸入寫到是資料區
        pthread_rwlock_unlock(&rwlock);    // 解鎖
        sleep(15); // 等待
    }
    pthread_rwlock_unlock(&rwlock);       // 解鎖
    pthread_exit(0);               // 執行緒退出
}

void *thread_function_write_t(void *arg)  // 寫執行緒two,同one
{
    sleep(10);
    while(!time_to_exit)
    {
        pthread_rwlock_wrlock(&rwlock);
        printf("this is write thread two.\nInput some text. Enter 'end' to finish\n"); 
        fgets(work_area, WORK_SIZE, stdin);
        pthread_rwlock_unlock(&rwlock);
        sleep(20);
    }
    pthread_rwlock_unlock(&rwlock);
    pthread_exit(0);
}


相關推薦

Linux程式設計學習筆記----執行程式設計執行同步機制互斥()

互斥鎖通訊機制 基本原理 互斥鎖以排他方式防止共享資料被併發訪問,互斥鎖是一個二元變數,狀態為開(0)和關(1),將某個共享資源與某個互斥鎖邏輯上繫結之後,對該資源的訪問操作如下: (1)在訪問該資源之前需要首先申請互斥鎖,如果鎖處於開狀態,則申請得到鎖並立即上鎖(關),防

Linux程式設計學習筆記----執行程式設計執行同步條件變數

轉載請註明出處:http://blog.csdn.net/suool/article/details/38582521. 基本概念與原理 互斥鎖能夠解決資源的互斥訪問,但是在某些情況下,互斥並不能解決問題,比如兩個執行緒需 要互斥的處理各自的操作,但是一個執行緒的操作僅僅存

面試筆記(一):系統程式設計執行同步——互斥、訊號、條件變數)

1.linux下執行緒同步的方式(轉自:https://blog.csdn.net/Shannon_ying/article/details/51280623、https://blog.csdn.net/q_l_s/article/details/44117929)執行緒的最

Python語言程式設計-學習筆記2:Python程式設計基本方法

第一週:Python程式設計之基本方法 1.1 課程內容和安排介紹 入門課; 十週; 課程內容: 基本設計方法;1-2 語法;3-6 高階;7-8 有趣的程式設計;9-10 1.2 從計算機到程式設計語言 1.計算機: 計算機:根據指令操作資料;     功能性;

linux執行同步機制訊號互斥、條件變數

之前有寫過類似的部落格,這東西不用老忘,現在又有更清晰的理解了。 一、訊號量 編譯時候加入-lrt 訊號量最基本的兩個操作就是PV操作:P()操作實現訊號量減少,V()操作實現訊號量的增加 訊號量的值取決於訊號量的型別,訊號量的型別有多種: (1)二進位制訊號量:0與1.

執行設計模式:第三篇 - 生產者-消費者模式和模式

一,生產者-消費者模式         生產者-消費者模式是比較常見的一種模式,當生產者和消費者都只有一個的時候,這種模式也被稱為 Pipe模式,即管道模式。      &nb

JAVA執行 重入

在java多執行緒中,我們真的可以使用synchronized關鍵字來實現執行緒間的同步互斥工作,那麼其實還有一個更優秀的機制去完成這個“同步互斥”工作,他就是Lock物件,重入鎖和讀寫鎖。他們具有比synchronized更為強大的功能,並且有嗅探鎖定、多路分支等功能。 一、重入鎖

018.執行-悲觀、樂觀、重入、自旋、CAS無機制

悲觀鎖(Pessimistic Lock) 顧名思義,就是很悲觀。每次去拿資料的時候都認為別人會修改,所以都會上鎖。這樣別人想拿這個資料就會阻塞(block)直到它拿到鎖。傳統的關係型資料庫裡面就用到了很多這種鎖機制。比如:行鎖,表鎖,讀鎖,寫鎖等,都是在做操作之前先上鎖。

四十、Linux 執行——互斥

40.1 互斥鎖 40.1.1 介紹 互斥鎖(mutex)是一種簡單的加鎖的方法來控制對共享資源的訪問。 在同一時刻只能有一個執行緒掌握某個互斥鎖,擁有上鎖狀態的執行緒能夠對共享資源進行訪問。 若其他執行緒希望上鎖一個已經被上了互斥鎖的資源,則該執行緒掛起,直到上鎖的執行緒釋

Java併發程式設計(10)-顯式的使用

文章目錄 一、顯式鎖 1.1、什麼是顯式鎖 1.2、Lock和ReentrantLock 1.3、如何使用顯示鎖 二、讀寫鎖 2.1、為什麼使用讀寫鎖

Lock、synchronized=====可重入、可中斷、公平====CountDownLatch、CyclicBarrier 、join()、執行

Lock、synchronized Synchronized 如果一個程式碼塊被synchronized修飾了,當一個執行緒獲取了對應的鎖,並執行該程式碼塊時,其他執行緒便只能一直等待,等待獲取鎖的執行緒釋放鎖,而這裡獲取鎖的執行緒釋放鎖只會有兩種情況:   1)獲取鎖的執行緒

Java併發程式設計札記-(四)JUC-07的升級—StampedLock

StampedLock是JDK1.8新增的一個鎖,是對讀寫鎖ReentrantReadWriteLock的改進。前面已經學習了ReentrantReadWriteLock,我們瞭解到,在共享資料很大,且讀操作遠多於寫操作的情況下,ReentrantReadWri

筆記:程序間通訊——同步(互斥、條件變數、訊號)以及Linux中的RCU

1.互斥鎖 多個執行緒的IPC,需要同步,同步有隱式的和顯示的: 比如unix提供的管道和FIFO,由核心負責同步,比如read發生在write之前,那麼read就會被核心阻塞,這中同步是由核心負責的,使用者不會感知。 但如果使用共享區作為生產者和消費者之間的IPC,那麼程

執行同步機制互斥,自旋,條件變數,屏障)

先知:      (1)執行緒是由程序建立而來,是cpu排程的最小單位。      (2)每個程序都有自己獨立的地址空間,而程序中的多個執行緒共用程序的資源,他們只有自己獨立的棧資源。 執行緒同步:      當多個控制執行緒共享相同的記憶體時,需要確保每個程序看到一致的

linux同步機制互斥

 版權宣告:如有需要,可供轉載,但請註明出處:https://blog.csdn.net/City_of_skey/article/details/85494572   目錄 1、簡介 2、API 2.1 pthread_mutex_init 2.2 pt

Linux核心同步機制訊號互斥

訊號量:訊號量(semaphore)是程序間通訊處理同步互斥的機制。是在多執行緒環境下使用的一種措施,它負責協調各個程序,以保證他們能夠正確、合理的使用公共資源。 它和spin lock最大的不同之處就是:無法獲取訊號量的程序可以睡眠,因此會導致系統排程。原理訊號量一般可以用

linux同步機制訊號down 和up

訊號量(semaphore)   Linux核心的訊號量在概念和原理上和使用者態的System V的IPC機制訊號量是相同的,不過他絕不可能在核心之外使用,因此他和System V的IPC機制訊號量毫不相干。   訊號量在建立時需要設定一個初始值,表示同時能有幾個任務能訪問

java學習筆記-執行程式設計模擬十個人過山洞

編寫多執行緒應用程式,模擬多個人通過一個山洞的模擬。這個山洞每次只能通過一個人,每個人通過山洞的時間為5秒,隨機生成10個人,同時準備過此山洞,顯示一下每次通過山洞人的姓名。   使用執行緒同步,把山洞看做臨界資源,五秒內只允許一個人來訪問。 class cave { p

學習筆記-執行程式設計執行同步

    執行緒基礎  程序與執行緒 我們執行一個exe,就是一個程序例項,系統中有很多個程序。每一個程序都有自己的記憶體地址空間,每個程序相當於一個獨立的邊界,有自己的獨佔的資源,程序之間不能共享程式碼和資料空間。 每一個程序有一個或多個執行緒,程