亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 為什么需要同步?

為什么需要同步? 時間:2018-09-26      來源:未知

1. 為什么需要同步?

上面的圖是從《高級編程》中截的圖,雖然它是針對線程的,但是這里要說明,不僅僅線程要考慮這個問題,只要涉及到并發的程序,都要考慮同步。比如多進程共享內存,比如某個驅動會同時被打開,而且會被幾個進程同時修改驅動中的值或者寄存器......

原理上都是一樣的,多線程并發訪問是一定要注意的,因為同一進程的多個線程本身就共享進程資源或者說變量的內存。就拿上圖來說,我們對i變量的值+1操作,那么這個簡簡單單的+1操作真正到了CPU上會怎么執行呢?通常分為3步:

(1) 從內存單元讀入寄存器

(2) 在寄存器上進行變量值增加

(3) 把新的值寫回內存單元

這就導致了上圖的問題,A線程在把i從內存讀入寄存器改變過程中(還沒寫回到內存),B線程也對i做了同樣操作,以至于后結果就是讀入的都是5,寫入的都是6,那么本來我們是要對i增加2次的,實際卻增加了1次。這種操作時間問題可能發生在ns級別,但是以當今處理器動輒幾GHZ的速度來說,發生這種情況概率還是很大的。

2.驗證試驗

下面我們就做實驗來實際看看這種情況。

看下程序:

1. #include

2. #include

3. #include

4. #include

5.

6. #define NUM 40000000

7.

8. pthread_t tid1;

9. pthread_t tid2;

10.

11. unsigned int count1 = 0;

12. unsigned int count2 = 0;

13. unsigned int count = 0;

14.

15. void * thr_fn1(void *arg)

16. {

17. while(count1

18. {

19. count++;

20. count1++;

21. }

22. }

23.

24. void * thr_fn2(void *arg)

25. {

26. while(count2

27. {

28. count++;

29. count2++;

30. }

31. }

32.

33. int main(void)

34. {

35. int err;

36.

37. err = pthread_create(&tid1, NULL, thr_fn1, NULL);

38. if (err != 0)

39. perror("can't create thread1");

40.

41. err = pthread_create(&tid2, NULL, thr_fn2, NULL);

42. if (err != 0)

43. perror("can't create thread2");

44.

45. pthread_join(tid1, NULL);

46. pthread_join(tid2, NULL);

47.

48. printf("count = %u, count1 = %u, count2 = %u\n", count, count1, count2);

49. exit(0);

50. }

程序很簡單,就是創建兩個線程,然后每個線程分別對count增加40000000 值,這個值是我隨便選的,只要大一點就行,但是別超了2^32。而count1和count2分別來記錄兩個線程對count分別增加了多少次,其實有NUM控制就好了,不過為了對比,我們加入這兩個變量。主進程創建兩個線程后我們用pthread_join函數來等待兩個線程執行完畢,并打印三個值比較得出結果。

首先在PC機上看下結果,CPU是雙核2.6GHZ的,運行環境是ubuntu,順便用time命令查看下執行時間:

從上圖可以看出,兩個線程對count進行總共80000000次累加大概需要2ms多一點,測了6次有2次是有問題的,即count != count1 + count2,概率還是比較大的。

然后我把相同的代碼重新編譯拿到AM335x(TI A8單核600MHZ)運行,結果如下

這個時間程序耗時就明顯長了,需要大概4s,本來我以為單核處理器出錯概率會小,沒想到運行5次結果居然全是錯的。具體為什么會這樣沒去深究,猜想應該和SMP機制及操作系統線程調度有關。這個結果更證明了線程同步的重要性,尤其是在嵌入式系統中。

3.同步問題解決方案

既然問題都明白了,接下來當然是解決方案了,解決這種同步問題經典的方案就是鎖了,相信大部分人平時都用過。以linux線程庫提供的接口,代碼改為下面形式。

1. #define NUM 40000000

2. pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

3.

4. pthread_t tid1;

5. pthread_t tid2;

6.

7. unsigned int count1 = 0;

8. unsigned int count2 = 0;

9. unsigned int count = 0;

10.

11. void * thr_fn1(void *arg)

12. {

13. while(count1

14. {

15. pthread_mutex_lock(&lock);

16. count++;

17. pthread_mutex_unlock(&lock);

18.

19. count1++;

20. }

21. }

22.

23. void * thr_fn2(void *arg)

24. {

25. while(count2

26. {

27. pthread_mutex_lock(&lock);

28. count++;

29. pthread_mutex_unlock(&lock);

30.

31. count2++;

32. }

33. }

只列出了部分代碼,其它的都一樣,其實思想很簡單,就是在并發訪問同一個變量時候,給這個共享變量加鎖,保證寫操作的原子性即可。那么為什么count1和count2不用加鎖呢,因為兩個變量本身就只在兩個線程中分別操作,所以沒必要加鎖。

后來看下結果,問題本身已經解決了,但是這次重點不在結果上,而在程序執行時間上。這是在PC上結果:

這是在ARM上的結果:

加了這個操作后,PC上同一程序運行時間多了10倍,板子上多了6倍。所以加鎖操作在保證了并發訪問正確性同時,大大增加了程序運行時間。所以我們在多進程共享資源并發訪問程序設計時候,需要綜合考慮程序的正確性和效率。

上一篇:如何破解嵌入式產品的telnet密碼

下一篇:Kotlin語法

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 3344成年站福利在线视频免费 | 亚洲天堂成人在线观看 | 国产青草视频在线观看免费影院 | 欧美日韩激情在线一区 | 玖操在线| 人人射人人 | www.youjizz.com在线播放 | 欧美一a一片一级一片 | 黄色成人在线 | 久久久久女人精品毛片九一 | 久久91精品牛牛 | 国产日本亚洲欧美 | 欧美午夜在线观看理论片 | 日本黄色片免费看 | 国产麻豆剧传媒精品网站 | 日本免费人成黄页在线观看视频 | 欧美猛黑又粗又长xxxx乱 | 天天色踪合合 | 欧美一区二区三区在线观看 | 高清色惰www日本午夜 | 黑人性猛交xxxx乱大交一 | 欧美性色高清生活片 | 久草免费在线观看 | 日本网络视频www色高清免费 | 精品国产综合区久久久久久 | aaa毛片手机在线现看 | 久久观看午夜精品 | 韩国一级成a人片在线观看 韩国一级黄色 | 手机看片日韩日韩国产在线看 | 精品视频一区二区三区免费 | 天天草夜夜操 | 亚洲天天在线 | 亚洲 日本 欧美 中文幕 | 青青草网站在线观看 | 欧美jizzhd欧美巨大 | 久久国产精品-国产精品 | 色综合免费视频 | 日本成人在线看 | 久久91精品综合国产首页 | 日本三级香港三级三级人!妇久 | 国产在线精品一区二区高清不卡 |