日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
深入解析LinuxC多線程同步技術(shù)(linuxc多線程同步)

隨著計算機(jī)系統(tǒng)的不斷提升,多核CPU逐漸成為高性能計算機(jī)的核心部分,多線程編程也逐漸成為軟件開發(fā)領(lǐng)域的熱門技術(shù)之一。在多線程編程中,線程同步是一個必不可少的操作,而linux c多線程同步技術(shù)是實(shí)現(xiàn)線程同步的關(guān)鍵。

本文將圍繞Linux C多線程同步技術(shù)展開深入解析,主要包括以下幾個方面:多進(jìn)程同步機(jī)制、多線程同步機(jī)制、pthread庫的使用、互斥鎖、條件變量、信號量等內(nèi)容。

一、多進(jìn)程同步機(jī)制

在Linux操作系統(tǒng)中,多進(jìn)程之間的通信和同步涉及到諸多機(jī)制,例如管道、socket、消息隊列、共享內(nèi)存等。其中,共享內(nèi)存是一種特殊的內(nèi)存區(qū)域,可以被多個進(jìn)程進(jìn)行訪問,從而實(shí)現(xiàn)進(jìn)程之間的通信和同步。

共享內(nèi)存是一種直接通信機(jī)制,因為進(jìn)程可以直接訪問共享內(nèi)存,而不需要進(jìn)行系統(tǒng)調(diào)用。同時,共享內(nèi)存機(jī)制提供了一些同步機(jī)制,例如信號量、互斥鎖等,可用于控制進(jìn)程之間對共享內(nèi)存數(shù)據(jù)的訪問順序。

二、多線程同步機(jī)制

Linux操作系統(tǒng)中,線程同步也涉及到各種機(jī)制,例如進(jìn)程間通信機(jī)制、互斥鎖、條件變量、信號量等。

在多線程編程中,互斥鎖是最常用的同步機(jī)制之一,用于控制對共享資源的訪問。具體來說,互斥鎖在對某一共享資源進(jìn)行操作時,先加鎖,操作完成后再釋放鎖,從而保證同一時刻只有一個線程對共享資源進(jìn)行訪問,避免了多個線程同時修改共享資源,從而導(dǎo)致數(shù)據(jù)不一致的問題。

此外,條件變量用于線程間的等待和通知。一般情況下,條件變量和互斥鎖一起使用,因為鎖能夠保證線程間的互斥操作,而條件變量則提供了一種線程間的等待和通知機(jī)制。

信號量是一種機(jī)制,用于控制對一組共享資源的訪問。當(dāng)一個線程需要進(jìn)行對共享資源的訪問時,它請求信號量,如果信號量的計數(shù)器大于0,那么線程就可以訪問共享資源,同時信號量的計數(shù)器將減一。如果信號量計數(shù)器為0,那么線程將處于等待狀態(tài),直到其他線程釋放了信號量,計數(shù)器才會增加,使得線程可以訪問到共享資源。

三、pthread庫的使用

Linux C多線程編程中,pthread庫是最基礎(chǔ)的庫之一,可以實(shí)現(xiàn)各種線程操作,例如創(chuàng)建線程、等待線程、終止線程等。常用的線程函數(shù)包括:pthread_create、pthread_join、pthread_attr_init、pthread_attr_destroy等。

pthread_create函數(shù)可用于創(chuàng)建線程,它的原型如下:

“`c

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)

“`

其中,thread參數(shù)是創(chuàng)建線程的ID,attr參數(shù)代表線程的屬性,start_routine函數(shù)是線程的入口函數(shù),arg參數(shù)是傳遞給線程入口函數(shù)的參數(shù)。

pthread_join函數(shù)是用于等待線程結(jié)束的函數(shù),其原型如下:

“`c

int pthread_join(pthread_t thread, void **retval)

“`

其中,thread參數(shù)代表需要等待的線程ID,retval參數(shù)為指向線程的退出狀態(tài)的指針。如果線程已經(jīng)結(jié)束,則pthread_join函數(shù)立即返回。

pthread_attr_init函數(shù)用于初始化線程屬性,pthread_attr_destroy函數(shù)用于釋放線程屬性所占用的資源。

四、互斥鎖

Linux C多線程編程中,互斥鎖是常用的同步機(jī)制之一。Linux提供了兩種類型的互斥鎖:PTHREAD_MUTEX_NORMAL(普通互斥鎖)和PTHREAD_MUTEX_RECURSIVE(遞歸互斥鎖)。

普通互斥鎖只能被解鎖一次,如果一個線程將普通互斥鎖解鎖多次,將導(dǎo)致未定義的行為。

遞歸互斥鎖可以被同一線程多次加鎖,每次加鎖時計數(shù)器加一,解鎖時計數(shù)器減一,只有計數(shù)器為0時,才能被其他線程加鎖。

互斥鎖使用時,首先需要初始化互斥鎖,然后使用pthread_mutex_lock函數(shù)加鎖,再使用pthread_mutex_unlock函數(shù)釋放鎖,如下所示:

“`c

pthread_mutex_t mutex;

void func() {

pthread_mutex_init(&mutex, NULL);

pthread_mutex_lock(&mutex);

// 此處進(jìn)行臨界區(qū)操作

pthread_mutex_unlock(&mutex);

pthread_mutex_destroy(&mutex);

}

“`

五、條件變量

Linux C多線程編程中,條件變量是線程間等待和通知的一種機(jī)制。條件變量的類型為pthread_cond_t,可以通過pthread_cond_init函數(shù)來初始化一個條件變量。

在使用條件變量時,通常需要與互斥鎖一起使用。因為條件變量本身并不提供鎖機(jī)制,可能會出現(xiàn)多個線程同時訪問的問題。當(dāng)一個線程需要等待條件變量時,應(yīng)該先加鎖,然后再等待條件變量的信號通知,如下所示:

“`c

pthread_mutex_t mutex;

pthread_cond_t cond;

void *func(void *arg) {

pthread_mutex_lock(&mutex);

while (condition) {

pthread_cond_wt(&cond, &mutex);

}

pthread_mutex_unlock(&mutex);

}

“`

在其它線程中,可以通過pthread_cond_signal或pthread_cond_broadcast函數(shù)來發(fā)送信號通知,如下所示:

“`c

pthread_mutex_t mutex;

pthread_cond_t cond;

int condition = 0;

void *func(void *arg) {

pthread_mutex_lock(&mutex);

condition = 1;

pthread_cond_signal(&cond); // 發(fā)送信號通知

pthread_mutex_unlock(&mutex);

}

“`

六、信號量

Linux C多線程編程中,信號量是一個最基本的同步機(jī)制,也是多進(jìn)程編程中最常用的同步手段。信號量是一種計數(shù)器,用于控制對一組共享資源的訪問。具體來說,當(dāng)一個線程需要訪問共享資源時,它向信號量請求一個鎖,如果計數(shù)器大于0,那么線程就可以訪問共享資源,同時計數(shù)器減一,如果計數(shù)器為0,那么線程將等待信號量的值發(fā)生變化。

Linux中提供了兩種類型的信號量:二進(jìn)制信號量和計數(shù)信號量。二進(jìn)制信號量只有兩種狀態(tài),一種是0,表示資源不可用,另一種是1,表示資源可用。計數(shù)信號量則是根據(jù)計數(shù)器的值來控制對共享資源的訪問,該值通常初始化為n,表示共享資源有n個。

在使用信號量時,首先需要創(chuàng)建信號量,然后使用sem_wt函數(shù)等待信號量,使用sem_post函數(shù)釋放信號量。

七、

本文主要圍繞Linux C多線程同步技術(shù)展開深入解析,分別從多進(jìn)程同步機(jī)制、多線程同步機(jī)制、pthread庫的使用、互斥鎖、條件變量、信號量等方面進(jìn)行介紹。同步機(jī)制是多線程編程中必不可少的部分,合理地使用同步機(jī)制可以有效避免線程之間的競爭和沖突,從而保證程序的正確性和穩(wěn)定性。

成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗豐富以策略為先導(dǎo)10多年以來專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站制作,設(shè)計師量身打造品牌風(fēng)格,熱線:028-86922220

linux 多進(jìn)程信號同步問題

朋友你好:希望能幫到你?;ハ鄬W(xué)習(xí)。

線程的更大特點(diǎn)是資源的共享性,但資源共享中的同步問題是多線程編程的難點(diǎn)。清敏linux下提供了多種方式來處理線程裂做同步,最常用的是互斥鎖、條件變量和信號量。

1)互斥鎖(mutex)

通過鎖機(jī)制實(shí)現(xiàn)線程間的同步。同一時刻只允許一個肆正衡線程執(zhí)行一個關(guān)鍵部分的代碼。

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

int pthread_mutex_lock(pthread_mutex *mutex);

int pthread_mutex_destroy(pthread_mutex *mutex);

int pthread_mutex_unlock(pthread_mutex *

(1)先初始化鎖init()或靜態(tài)賦值pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIER

attr_t有:

PTHREAD_MUTEX_TIMED_NP:其余線程等待隊列

PTHREAD_MUTEX_RECURSIVE_NP:嵌套鎖,允許線程多次加鎖,不同線程,解鎖后重新競爭

PTHREAD_MUTEX_ERRORCHECK_NP:檢錯,與一同,線程請求已用鎖,返回EDEADLK;

PTHREAD_MUTEX_ADAPTIVE_NP:適應(yīng)鎖,解鎖后重新競爭

(2)加鎖,lock,trylock,lock阻塞等待鎖,trylock立即返回EBUSY

(3)解鎖,unlock需滿足是加鎖狀態(tài),且由加鎖線程解鎖

(4)清除鎖,destroy(此時鎖必需unlock,否則返回EBUSY,//Linux下互斥鎖不占用內(nèi)存資源

示例代碼

#include

#include

#include

#include

#include “iostream”

using namespace std;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int tmp;

void* thread(void *arg)

{

cout

#include

#include “stdlib.h”

#include “unistd.h”

pthread_mutex_t mutex;

pthread_cond_t cond;

void hander(void *arg)

{

free(arg);

(void)pthread_mutex_unlock(&mutex);

}

void *thread1(void *arg)

{

pthread_cleanup_push(hander, &mutex);

while(1)

{

printf(“thread1 is running\n”);

pthread_mutex_lock(&mutex);

pthread_cond_wait(&cond,&mutex);

printf(“thread1 applied the condition\n”);

pthread_mutex_unlock(&mutex);

sleep(4);

}

pthread_cleanup_pop(0);

}

void *thread2(void *arg)

{

while(1)

{

printf(“thread2 is running\n”);

pthread_mutex_lock(&mutex);

pthread_cond_wait(&cond,&mutex);

printf(“thread2 applied the condition\n”);

pthread_mutex_unlock(&mutex);

sleep(1);

}

}

int main()

{

pthread_t thid1,thid2;

printf(“condition variable study!\n”);

pthread_mutex_init(&mutex,NULL);

pthread_cond_init(&cond,NULL);

pthread_create(&thid1,NULL,thread1,NULL);

pthread_create(&thid2,NULL,thread2,NULL);

sleep(1);

do

{

pthread_cond_signal(&cond);

}while(1);

sleep(20);

pthread_exit(0);

return 0;

}

示例程序2:

#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

{

int n_number;

struct node *n_next;

} *head = NULL;

/**/

static void cleanup_handler(void *arg)

{

printf(“Cleanup handler of second thread./n”);

free(arg);

(void)pthread_mutex_unlock(&mtx);

}

static void *thread_func(void *arg)

{

struct node *p = NULL;

pthread_cleanup_push(cleanup_handler, p);

while (1)

{

//這個mutex主要是用來保證pthread_cond_wait的并發(fā)性

pthread_mutex_lock(&mtx);

while (head == NULL)

{

//這個while要特別說明一下,單個pthread_cond_wait功能很完善,為何

//這里要有一個while (head == NULL)呢?因為pthread_cond_wait里的線

//程可能會被意外喚醒,如果這個時候head != NULL,則不是我們想要的情況。

//這個時候,應(yīng)該讓線程繼續(xù)進(jìn)入pthread_cond_wait

// pthread_cond_wait會先解除之前的pthread_mutex_lock鎖定的mtx,

//然后阻塞在等待對列里休眠,直到再次被喚醒(大多數(shù)情況下是等待的條件成立

//而被喚醒,喚醒后,該進(jìn)程會先鎖定先pthread_mutex_lock(&mtx);,再讀取資源

//用這個流程是比較清楚的/*block–>unlock–>wait() return–>lock*/

pthread_cond_wait(&cond, &mtx);

p = head;

head = head->n_next;

printf(“Got %d from front of queue/n”, p->n_number);

free(p);

}

pthread_mutex_unlock(&mtx); //臨界區(qū)數(shù)據(jù)操作完畢,釋放互斥鎖

}

pthread_cleanup_pop(0);

return 0;

}

int main(void)

{

pthread_t tid;

int i;

struct node *p;

//子線程會一直等待資源,類似生產(chǎn)者和消費(fèi)者,但是這里的消費(fèi)者可以是多個消費(fèi)者,而

//不僅僅支持普通的單個消費(fèi)者,這個模型雖然簡單,但是很強(qiáng)大

pthread_create(&tid, NULL, thread_func, NULL);

sleep(1);

for (i = 0; i n_number = i;

pthread_mutex_lock(&mtx); //需要操作head這個臨界資源,先加鎖,

p->n_next = head;

head = p;

pthread_cond_signal(&cond);

pthread_mutex_unlock(&mtx); //解鎖

sleep(1);

}

printf(“thread 1 wanna end the line.So cancel thread 2./n”);

//關(guān)于pthread_cancel,有一點(diǎn)額外的說明,它是從外部終止子線程,子線程會在最近的取消點(diǎn),退出

//線程,而在我們的代碼里,最近的取消點(diǎn)肯定就是pthread_cond_wait()了。

pthread_cancel(tid);

pthread_join(tid, NULL);

printf(“All done — exiting/n”);

return 0;

}

3)信號量

如同進(jìn)程一樣,線程也可以通過信號量來實(shí)現(xiàn)通信,雖然是輕量級的。

信號量函數(shù)的名字都以”sem_”打頭。線程使用的基本信號量函數(shù)有四個。

#include

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

這是對由sem指定的信號量進(jìn)行初始化,設(shè)置好它的共享選項(linux 只支持為0,即表示它是當(dāng)前進(jìn)程的局部信號量),然后給它一個初始值VALUE。

兩個原子操作函數(shù):

int sem_wait(sem_t *sem);

int sem_post(sem_t *sem);

這兩個函數(shù)都要用一個由sem_init調(diào)用初始化的信號量對象的指針做參數(shù)。

sem_post:給信號量的值加1;

sem_wait:給信號量減1;對一個值為0的信號量調(diào)用sem_wait,這個函數(shù)將會等待直到有其它線程使它不再是0為止。

int sem_destroy(sem_t *sem);

這個函數(shù)的作用是再我們用完信號量后都它進(jìn)行清理。歸還自己占有的一切資源。

示例代碼:

#include

#include

#include

#include

#include

#include

#define return_if_fail(p) if((p) == 0){printf (“:func error!/n”, __func__);return;}

typedef struct _PrivInfo

{

sem_t s1;

sem_t s2;

time_t end_time;

}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)

{

pthread_t pt_1 = 0;

pthread_t pt_2 = 0;

int ret = 0;

PrivInfo* thiz = NULL;

thiz = (PrivInfo* )malloc (sizeof (PrivInfo));

if (thiz == NULL)

{

printf (“: Failed to malloc priv./n”);

return -1;

}

info_init (thiz);

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

if (ret != 0)

{

perror (“pthread_1_create:”);

}

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

if (ret != 0)

{

perror (“pthread_2_create:”);

}

pthread_join (pt_1, NULL);

pthread_join (pt_2, NULL);

info_destroy (thiz);

return 0;

}

static void info_init (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);

thiz->end_time = time(NULL) + 10;

sem_init (&thiz->s1, 0, 1);

sem_init (&thiz->s2, 0, 0);

return;

}

static void info_destroy (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);

sem_destroy (&thiz->s1);

sem_destroy (&thiz->s2);

free (thiz);

thiz = NULL;

return;

}

static void* pthread_func_1 (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);

while (time(NULL) end_time)

{

sem_wait (&thiz->s2);

printf (“pthread1: pthread1 get the lock./n”);

sem_post (&thiz->s1);

printf (“pthread1: pthread1 unlock/n”);

sleep (1);

}

return;

}

static void* pthread_func_2 (PrivInfo* thiz)

{

return_if_fail (thiz != NULL);

while (time (NULL) end_time)

{

sem_wait (&thiz->s1);

printf (“pthread2: pthread2 get the unlock./n”);

sem_post (&thiz->s2);

printf (“pthread2: pthread2 unlock./n”);

sleep (1);

}

return;

}

通 過執(zhí)行結(jié)果后,可以看出,會先執(zhí)行線程二的函數(shù),然后再執(zhí)行線程一的函數(shù)。它們兩就實(shí)現(xiàn)了同步

創(chuàng)新互聯(lián)【028-86922220】值得信賴的成都網(wǎng)站建設(shè)公司。多年持續(xù)為眾多企業(yè)提供成都網(wǎng)站建設(shè),成都品牌建站設(shè)計,成都高端網(wǎng)站制作開發(fā),SEO優(yōu)化排名推廣服務(wù),全網(wǎng)營銷讓企業(yè)網(wǎng)站產(chǎn)生價值。


當(dāng)前題目:深入解析LinuxC多線程同步技術(shù)(linuxc多線程同步)
本文鏈接:http://www.dlmjj.cn/article/dhgoejo.html