Linux線程及同步

來源:互聯網
上載者:User

Linux多線程

 

1.線程概述

線程是一個進程內的基本調度單位,也可以稱為輕量級進程。線程是在共用記憶體空間中並發的多道執行路徑,它們共用一個進程的資源,如檔案描述和訊號處理。因此,大大減少了環境切換的開銷。一個進程可以有多個線程,也就

是有多個線程式控制製表及堆棧寄存器,但卻共用一個使用者地址空間。

 

2.線程實現

 

線程建立pthread_create()

  所需標頭檔#include <pthread.h>

函數原型int pthread_create ((pthread_t *thread, pthread_attr_t *attr,

void *(*start_routine)(void *), void *arg))

thread:線程標識符

attr:線程屬性設定

start_routine:線程函數的起始地址

arg:傳遞給start_routine的參數

函數傳回值 成功:0 出錯:-1

 

線程退出pthread_exit();

 所需標頭檔#include <pthread.h>

函數原型void pthread_exit(void *retval)

函數傳入值retval:pthread_exit()調用者線程的傳回值,可由其他函數如pthread_join 來檢索擷取

 

等待線程退出並釋放資源pthread_join()

  所需標頭檔#include <pthread.h>

函數原型int pthread_join ((pthread_t th, void **thread_return))

函數傳入值

th:等待線程的標識符

thread_return:使用者定義的指標,用來儲存被等待線程的傳回值(不為NULL時)

函數傳回值  成功:0  出錯:-1

 

代碼舉例

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.   

5.    /*線程1*/

6.    void thread1()

7.    {

8.        int i=0;

9.        

10.           while(1)

11.           {

12.        printf("thread1:%d\n",i);

13.        if(i>3)

14.           pthread_exit(0);

15.        i++;

16.        sleep(1);

17.       }

18.   }

19.  

20.   /*線程2*/

21.   void thread2()

22.   {

23.       int i=0;

24.       

25.           while(1)

26.           {

27.        printf("thread2:%d\n",i);

28.        if(i>5)

29.           pthread_exit(0);

30.        i++;

31.        sleep(1);

32.       }

33.   }

34.  

35.   int main()

36.   {

37.   pthread_t t1,t2;

38.  

39.   /*建立線程*/

40.   pthread_create(&t1,NULL,(void *)thread1,NULL);

41.   pthread_create(&t2,NULL,(void *)thread2,NULL);

42.   /*等待線程退出*/

43.   pthread_join(t1,NULL);

44.   pthread_join(t2,NULL);

45.   return 0;

46.   }

3同步與互斥

<1>互斥鎖

 互斥鎖的操作主要包括以下幾個步驟。

• 互斥鎖初始化:pthread_mutex_init

• 互斥鎖上鎖:pthread_mutex_lock

• 互斥鎖判斷上鎖:pthread_mutex_trylock

• 互斥鎖接鎖:pthread_mutex_unlock

• 消除互斥鎖:pthread_mutex_destroy

 

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.   

5.    int i=0;/*共用變數*/

6.    pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;/*互斥鎖*/

7.   

8.    void thread1()

9.    {

10.       int ret;

11.       while(1)

12.       {

13.           

14.        

15.        ret=pthread_mutex_trylock(&mutex);/*判斷上鎖*/

16.        

17.        if(ret!=EBUSY)

18.           {

19.           pthread_mutex_lock(&mutex);/*上鎖*/

20.           printf("This is thread1:%d\n",i);

21.          i++;

22.         pthread_mutex_unlock(&mutex);/*解鎖*/

23.        }

24.        sleep(1);

25.       }

26.   }

27.  

28.   void thread2()

29.   {int ret;

30.       while(1)

31.       {

32.        

33.        ret=pthread_mutex_trylock(&mutex);

34.        if(ret!=EBUSY)

35.           {

36.           pthread_mutex_lock(&mutex);

37.           printf("This is thread2:%d\n",i);

38.          i++;

39.         pthread_mutex_unlock(&mutex);

40.        }

41.        sleep(1);

42.       }

43.   }

44.   int main()

45.   {

46.   pthread_t t1,t2;

47.   pthread_mutex_init(&mutex,NULL);

48.   pthread_create(&t1,NULL,(void *)thread1,NULL);

49.   pthread_create(&t2,NULL,(void *)thread2,NULL);

50.    

51.   pthread_join(t1,NULL);

52.   pthread_join(t2,NULL);

53.    

54.   pthread_mutex_destroy(&mutex);

55.   return 0;

56.   }

<2>訊號量

未進行同步處理的兩個線程

 

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.   

5.    int i=0;

6.    void thread1()

7.    {

8.        

9.        while(1)

10.       {  

11.           printf("This is thread1:%d\n",i);

12.         i++;

13.         sleep(1);

14.     }

15.   }

16.  

17.  

18.   void thread2()

19.   {

20.  

21.       while(1)

22.       {  

23.           printf("This is thread2:%d\n",i);

24.         i++;

25.         sleep(1);

26.     }

27.   }

28.  

29.   int main()

30.   {

31.   pthread_t t1,t2;

32.  

33.   pthread_create(&t1,NULL,(void *)thread1,NULL);

34.   pthread_create(&t2,NULL,(void *)thread2,NULL);

35.    

36.   pthread_join(t1,NULL);

37.   pthread_join(t2,NULL);

38.    

39.   return 0;

40.   }

執行結果如下:

This is thread1:0

This is thread2:1

This is thread2:2

This is thread1:3

This is thread2:4

This is thread1:4

This is thread2:6

This is thread1:7

......

可以看出:

1.線程2的執行並非必須線上程1之後,如果要求線程2必須線上程1之後執行,稱為同步

2.線程1和線程2可能對共用變數i的同時進行讀取,如果要求每次只有一個線程讀取i,成為互斥

 

訊號量的使用

•sem_init用於建立一個訊號量,並能初始化它的值。

•sem_wait和sem_trywait相當於P操作,它們都能將訊號量的值減一,兩者的區別在於若訊號量小於零時,   sem_wait將會阻塞進程,而sem_trywait則會立即返回。

•sem_post相當於V操作,它將訊號量的值加一同時發出訊號喚醒等待的進程。

•sem_getvalue用於得到訊號量的值。

•sem_destroy用於刪除訊號量

 

 

代碼

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.    #include <semaphore.h>

5.   

6.   

7.    int i=0;

8.    sem_t sem1,sem2;

9.   

10.  

11.   void thread1()

12.   {

13.       

14.       while(1)

15.       {  

16.             sem_wait(&sem1);

17.           printf("This is thread1:%d\n",i);

18.         i++;

19.         sleep(3);/*線程1休眠3s,以便觀察線程2在輸出3s後才會執行*/

20.         sem_post(&sem2);

21.         

22.     }

23.   }

24.  

25.  

26.   void thread2()

27.   {

28.  

29.       while(1)

30.       {  

31.           sem_wait(&sem2);

32.           printf("This is thread2:%d\n",i);

33.         i++;

34.         sem_post(&sem1);

35.         sleep(1);

36.     }

37.   }

38.  

39.   int main()

40.   {

41.   pthread_t t1,t2;

42.  

43.    

44.  

45.   sem_init(&sem1,0,1);/*初始化訊號量sem1*/

46.   sem_init(&sem2,0,0);

47.  

48.   pthread_create(&t1,NULL,(void *)thread1,NULL);

49.   pthread_create(&t2,NULL,(void *)thread2,NULL);

50.    

51.   pthread_join(t1,NULL);

52.   pthread_join(t2,NULL);

53.    

54.   return 0;

55.   }

 

 

 

1.    #include<pthread.h>

2.    #include<stdio.h>

3.    #include<errno.h>

4.    #include <semaphore.h>

5.   

6.   

7.    int i=0;

8.    sem_t sem;

9.   

10.  

11.   void thread1()

12.   {

13.       

14.       while(1)

15.       {  

16.             sem_wait(&sem);

17.           printf("This is thread1:%d\n",i);

18.         i++;

19.         sleep(3);/*線程1休眠3s,以便觀察線程2在輸出3s後才會執行*/

20.         sem_post(&sem);

21.         

22.     }

23.   }

24.  

25.  

26.   void thread2()

27.   {

28.  

29.       while(1)

30.       {  

31.           sem_wait(&sem);

32.           printf("This is thread2:%d\n",i);

33.         i++;

34.         sem_post(&sem);

35.         sleep(1);

36.     }

37.   }

38.  

39.   int main()

40.   {

41.   pthread_t t1,t2;

42.  

43.    

44.  

45.   sem_init(&sem,0,1);/*初始化訊號量sem*/

46.  

47.   pthread_create(&t1,NULL,(void *)thread1,NULL);

48.   pthread_create(&t2,NULL,(void *)thread2,NULL);

49.    

50.   pthread_join(t1,NULL);

51.   pthread_join(t2,NULL);

52.    

53.   return 0;

54.   }

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.