linux線程同步之互斥鎖——linux的關鍵地區

來源:互聯網
上載者:User

在windows中,為了讓多個線程達到同步的目的,在對於全域變數等大家都要用的資源的使用上,通常得保證同時只能由一個線程在用,一個線程沒有宣布對它的釋放之前,不能夠給其他線程使用這個變數。在windows裡,我們可以用時EnterCriticalSection()和LeaveCriticalSection()函數.那麼在linux裡,有什麼類似的機制呢?

 

這裡介紹互斥鎖。

1.申請一個互斥鎖

pthread_mutex_t mutex; //申請一個互斥鎖

你可以聲明多個互斥量。

在聲明該變數後,你需要調用pthread_mutex_init()來建立該變數。pthread_mutex_init的格式如下:

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

第一個參數,mutext,也就是你之前聲明的那個互斥量,第二個參數為該互斥量的屬性。屬性定義如下:

互斥量分為下面三種:

l         快速型(PTHREAD_MUTEX_FAST_NP)。這種類型也是預設的類型。該線程的行為正如上面所說的。

l         遞迴型(PTHREAD_MUTEX_RECURSIVE_NP)。如果遇到我們上面所提到的死結情況,同一線程迴圈給互斥量上鎖,那麼系統將會知道該上鎖行為來自同一線程,那麼就會同意線程給該互斥量上鎖。

l         錯誤偵測型(PTHREAD_MUTEX_ERRORCHECK_NP)。如果該互斥量已經被上鎖,那麼後續的上鎖將會失敗而不會阻塞,pthread_mutex_lock()操作將會返回EDEADLK。

 

可以通過函數

注意以下語句可以做到將一個互斥鎖快速初始化為快速型。

pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;

 

2.銷毀一個互斥鎖

pthread_mutex_destroy()用於登出一個互斥鎖,API定義如下:

 int pthread_mutex_destroy(pthread_mutex_t *mutex)

銷毀一個互斥鎖即意味著釋放它所佔用的資源,且要求鎖當前處於開放狀態。由於在Linux中,互斥鎖並不佔用任何資源,因此LinuxThreads中的pthread_mutex_destroy()除了檢查鎖狀態以外(鎖定狀態則返回EBUSY)沒有其他動作。

 

3.上鎖(相當於windows下的EnterCriticalSection)

在建立該互斥量之後,你便可以使用它了。要得到互斥量,你需要調用下面的函數:

int pthread_mutex_lock(pthread_mutex_t *mutex);

該函數用來給互斥量上鎖。互斥量一旦被上鎖後,其他線程如果想給該互斥量上鎖,那麼就會阻塞在這個操作上。如果在此之前該互斥量已經被其他線程上鎖,那麼該操作將會一直阻塞在這個地方,直到獲得該鎖為止。

在得到互斥量後,你就可以進入關鍵代碼區了。 

 

4.解鎖(相當於windows下的LeaveCriticalSection)

在操作完成後,你必須調用下面的函數來給互斥量解鎖,也就是前面所說的釋放。這樣其他等待該鎖的線程才有機會獲得該鎖,否則其他線程將會永遠阻塞。

int pthread_mutex_unlock(pthread_mutex_t *mutex);

 

5.pthread_mutex_trylock

如果我們不想一直阻塞在這個地方,那麼可以調用下面函數:

int pthread_mutex_trylock(pthread_mutex_t *mutex)

如果此時互斥量沒有被上鎖,那麼pthread_mutex_trylock()將會返回0,並會對該互斥量上鎖。如果互斥量已經被上鎖,那麼會立刻返回EBUSY。

 

使用範例程式碼如下:

 

#include <malloc.h>

#include <pthread.h>

struct job {

    /* Link field for linked list. */

    struct job* next;

    /* Other fields describing work to be done */

};

/* A linked list of pending jobs. */

struct job* job_queue;

/* A mutex protecting job_queue. */

pthread_mutex_t job_queue_mutex = PTHREAD_MUTEX_INITIALIZER;

/* Process queued jobs until the queue is empty. */

void* thread_function (void* arg)

{

    while (1) {

        struct job* next_job;

        /* Lock the mutex on the job queue. */

        pthread_mutex_lock (&job_queue_mutex);

        /* Now it’s safe to check if the queue is empty. */

        if (job_queue == NULL)

            next_job = NULL;

        else {

            /* Get the next available job. */

            next_job = job_queue;

            /* Remove this job from the list. */

            job_queue = job_queue->next;

        }

        /* Unlock the mutex on the job queue because we’re done with the

        queue for now. */

        pthread_mutex_unlock (&job_queue_mutex);

        /* Was the queue empty? If so, end the thread. */

        if (next_job == NULL)

            break;

        /* Carry out the work. */

        process_job (next_job);

        /* Clean up. */

        free (next_job);

    }

    return NULL;

}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.