linux 執行緒同步

2021-07-24 19:41:56 字數 4712 閱讀 7588



執行緒的最大特點是資源的共享性,但資源共享中的同步問題是多執行緒程式設計的難點。linux下提供了多種方式來處理執行緒同步,最常用的是互斥鎖、條件變數和訊號量。

通過鎖機制實現執行緒間的同步。

初始化鎖。在linux下,執行緒的互斥量資料型別是pthread_mutex_t。在使用前,要對它進行初始化。

靜態分配:pthread_mutex_t mutex = pthread_mutex_initializer;

動態分配:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);

加鎖。對共享資源的訪問,要對互斥量進行加鎖,如果互斥量已經上了鎖,呼叫執行緒會阻塞,直到互斥量被解鎖。

int pthread_mutex_lock(pthread_mutex *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

解鎖。在完成了對共享資源的訪問後,要對互斥量進行解鎖。

int pthread_mutex_unlock(pthread_mutex_t *mutex);

銷毀鎖。鎖在是使用完成後,需要進行銷毀以釋放資源。

int pthread_mutex_destroy(pthread_mutex *mutex);

#include #include #include #include #include "iostream"

using namespace std;

pthread_mutex_t mutex = pthread_mutex_initializer;

int tmp;

void* thread(void *arg)

int main()

else

pthread_join(id, null);

pthread_mutex_destroy(&mutex);

return 0;

}//編譯:g++ -o thread testthread.cpp -lpthread

互斥鎖不同,條件變數是用來等待而不是用來上鎖的。條件變數用來自動阻塞乙個執行緒,直到某特殊情況發生為止。通常條件變數和互斥鎖同時使用。條件變數分為兩部分: 條件和變數。條件本身是由互斥量保護的。執行緒在改變條件狀態前先要鎖住互斥量。條件變數使我們可以睡眠等待某種條件出現。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作:乙個執行緒等待"條件變數的條件成立"而掛起;另乙個執行緒使"條件成立"(給出條件成立訊號)。條件的檢測是在互斥鎖的保護下進行的。如果乙個條件為假,乙個執行緒自動阻塞,並釋放等待狀態改變的互斥鎖。如果另乙個執行緒改變了條件,它發訊號給關聯的條件變數,喚醒乙個或多個等待它的執行緒,重新獲得互斥鎖,重新評價條件。如果兩程序共享可讀寫的記憶體,條件變數可以被用來實現這兩程序間的執行緒同步。

初始化條件變數。

靜態態初始化,pthread_cond_t cond = pthread_cond_initialier;

動態初始化,int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

等待條件成立。釋放鎖,同時阻塞等待條件變數為真才行。timewait()設定等待時間,仍未signal,返回etimeout(加鎖保證只有乙個執行緒wait)

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);

啟用條件變數。pthread_cond_signal,pthread_cond_broadcast(啟用所有等待執行緒)

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond); //解除所有執行緒的阻塞

清除條件變數。無線程等待,否則返回ebusy

int pthread_cond_destroy(pthread_cond_t *cond);

#include #include #include "stdlib.h"

#include "unistd.h"

pthread_mutex_t mutex;

pthread_cond_t cond;

void hander(void *arg)

void *thread1(void *arg)

pthread_cleanup_pop(0);

}void *thread2(void *arg)

}int main()

while(1);

sleep(20);

pthread_exit(0);

return 0;

}

#include #include #include "stdio.h"

#include "stdlib.h"

static pthread_mutex_t mtx = pthread_mutex_initializer;

static pthread_cond_t cond = pthread_cond_initializer;

struct node

*head = null;

static void cleanup_handler(void *arg)

static void *thread_func(void *arg)

pthread_mutex_unlock(&mtx); //臨界區資料操作完畢,釋放互斥鎖

} pthread_cleanup_pop(0);

return 0;

}int main(void)

printf("thread 1 wanna end the line.so cancel thread 2./n");

//關於pthread_cancel,有一點額外的說明,它是從外部終止子執行緒,子執行緒會在最近的取消點,退出

//執行緒,而在我們的**裡,最近的取消點肯定就是pthread_cond_wait()了。

pthread_cancel(tid);

pthread_join(tid, null);

printf("all done -- exiting/n");

return 0;

}

如同程序一樣,執行緒也可以通過訊號量來實現通訊,雖然是輕量級的。訊號量函式的名字都以"sem_"打頭。執行緒使用的基本訊號量函式有四個。

訊號量初始化。

int sem_init (sem_t *sem , int pshared, unsigned int value);

這是對由sem指定的訊號量進行初始化,設定好它的共享選項(linux 只支援為0,即表示它是當前程序的區域性訊號量),然後給它乙個初始值value。

等待訊號量。給訊號量減1,然後等待直到訊號量的值大於0。

int sem_wait(sem_t *sem);

釋放訊號量。訊號量值加1。並通知其他等待執行緒。

int sem_post(sem_t *sem);

銷毀訊號量。我們用完訊號量後都它進行清理。歸還占有的一切資源。

int sem_destroy(sem_t *sem);

#include #include #include #include #include #include #define return_if_fail(p) if((p) == 0)

typedef struct _privinfo

privinfo;

static void info_init (privinfo* thiz);

static void info_destroy (privinfo* thiz);

static void* pthread_func_1 (privinfo* thiz);

static void* pthread_func_2 (privinfo* thiz);

int main (int argc, char** argv)

info_init (thiz);

ret = pthread_create (&pt_1, null, (void*)pthread_func_1, thiz);

if (ret != 0)

ret = pthread_create (&pt_2, null, (void*)pthread_func_2, thiz);

if (ret != 0)

pthread_join (pt_1, null);

pthread_join (pt_2, null);

info_destroy (thiz);

return 0;

}static void info_init (privinfo* thiz)

static void info_destroy (privinfo* thiz)

static void* pthread_func_1 (privinfo* thiz)

return;

}static void* pthread_func_2 (privinfo* thiz)

return;

}

linux 執行緒 執行緒同步

因為執行緒獨自擁有的只有棧,其他的區域執行緒共同擁有。並且對共享區域的操作並不都是原子的。對共享區域的操作順序又是不確定的。就像建立兩個檔案描述符同時指向 同一檔案,並且連續向檔案中寫入那麼寫的東西可能是亂七八糟的。這時就需要執行緒對共享區的同步。而另一種情況是,多個執行緒的指令執行順序需要同步。這...

Linux執行緒同步

1.概要 執行緒的同步,發生在多個執行緒共享相同記憶體的時候,這時,要保證每個執行緒在每個時刻看到的共享資料是一致的。如果每個執行緒使用的變數都是其他執行緒不會使用的 read write 或者變數是唯讀的,就不存在一致性問題。但是,如果兩個或兩個以上的執行緒可以read write乙個變數時,就需...

Linux執行緒同步

1.概要 執行緒的同步,發生在多個執行緒共享相同記憶體的時候,這時,要保證每個執行緒在每個時刻看到的共享資料是一致的。如果每個執行緒使用的變數都是其他執行緒不會使用的 read write 或者變數是唯讀的,就不存在一致性問題。但是,如果兩個或兩個以上的執行緒可以read write乙個變數時,就需...