亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2608 | 回復(fù): 6
打印 上一主題 下一主題

[Linux] linux 線程在未同步的情況下,輸出著實沒看懂! [復(fù)制鏈接]

論壇徽章:
1
巨蟹座
日期:2014-03-18 23:44:30
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2014-04-05 22:42 |只看該作者 |倒序瀏覽
  1. /*使用原子鎖實現(xiàn)線程同步*/

  2. #include <alsa/iatomic.h>
  3. #include <pthread.h>
  4. #include <stdio.h>

  5. // 定義一個原子變量
  6. static atomic_t g_atomic;
  7. // 定義共享資源
  8. static volatile int g_i = 0;

  9. /* 定義線程處理函數(shù) */
  10. #define atomic_dec_and_test(g_atomic) 1
  11. void *thr1_handle(void *arg)
  12. {
  13.     while (1) {
  14.         if (atomic_dec_and_test(&g_atomic)) {
  15.             printf("in thread %lu g_i = %d\n", pthread_self(), ++g_i);
  16.         }
  17.         atomic_inc(&g_atomic);
  18.         sleep(1);
  19.     }

  20.     return NULL;   
  21. }

  22. void *thr2_handle(void *arg)
  23. {
  24.     while (1) {
  25.         if (atomic_dec_and_test(&g_atomic)) {
  26.             printf("in thread %lu g_i = %d\n", pthread_self(), --g_i);
  27.         }
  28.         atomic_inc(&g_atomic);
  29.         sleep(1);
  30.     }
  31.     return NULL;   
  32. }


  33. /* 主函數(shù) */
  34. int main()
  35. {
  36.     // 主線程初始化原子變量
  37.     //g_atomic = ATOMIC_INIT(0);
  38.     g_atomic.counter = 1;

  39.     pthread_t tid1, tid2;
  40.     if (pthread_create(&tid1, NULL, thr1_handle, NULL) != 0) {
  41.         fprintf(stderr, "create thread1 failed!\n");
  42.         return 1;
  43.     }
  44.     if (pthread_create(&tid2, NULL, thr2_handle, NULL) != 0) {
  45.         fprintf(stderr, "create thread2 failed!\n");
  46.         return 2;
  47.     }

  48.     pthread_join(tid1, NULL);
  49.     pthread_join(tid2, NULL);

  50.     return 0;
  51. }
復(fù)制代碼
在不使用原子操作來做同步的情況下,程序輸出如下:

  1. in thread 3075713856 g_i = 1
  2. in thread 3067321152 g_i = 0
  3. in thread 3067321152 g_i = -1
  4. in thread 3075713856 g_i = 1
  5. in thread 3067321152 g_i = 0
  6. in thread 3075713856 g_i = 1
  7. in thread 3075713856 g_i = 2
  8. [color=Red]in thread 3067321152 g_i = 0
  9. in thread 3075713856 g_i = 3
  10. in thread 3067321152 g_i = 1
  11. in thread 3075713856 g_i = 4
  12. in thread 3067321152 g_i = 2
  13. in thread 3075713856 g_i = 5
  14. in thread 3067321152 g_i = 3
  15. in thread 3075713856 g_i = 6[/color]
  16. in thread 3067321152 g_i = 5
  17. in thread 3067321152 g_i = 4
  18. in thread 3075713856 g_i = 6
  19. in thread 3075713856 g_i = 5
  20. in thread 3067321152 g_i = 3
  21. in thread 3075713856 g_i = 6
  22. in thread 3067321152 g_i = 4
  23. in thread 3067321152 g_i = 3
  24. in thread 3075713856 g_i = 5
  25. in thread 3075713856 g_i = 6
  26. in thread 3067321152 g_i = 4
  27. in thread 3067321152 g_i = 5
  28. in thread 3075713856 g_i = 6
  29. in thread 3075713856 g_i = 7
  30. in thread 3067321152 g_i = 5
復(fù)制代碼
在輸出標(biāo)紅的部分,線程切換時為什么值會出現(xiàn)跳躍增加或減少呢?
按照程序邏輯,在沒進(jìn)入線程一次,只做一次值的加或減呀,怎是怎么個情況? 期待大V指點下

論壇徽章:
4
白羊座
日期:2013-09-17 21:59:30技術(shù)圖書徽章
日期:2013-10-12 22:16:03白羊座
日期:2013-10-14 11:01:40雙子座
日期:2013-12-17 18:26:39
2 [報告]
發(fā)表于 2014-04-06 00:23 |只看該作者
將++g_i(或--g_i)理解為一下三句,就能解釋這樣的輸出產(chǎn)生的原因:
register = memory(g_i);
register = register + 1(或register = register - 1);
memory(g_i) = register;

論壇徽章:
1
巨蟹座
日期:2014-03-18 23:44:30
3 [報告]
發(fā)表于 2014-04-06 02:10 |只看該作者
井蛙夏蟲 發(fā)表于 2014-04-06 00:23
將++g_i(或--g_i)理解為一下三句,就能解釋這樣的輸出產(chǎn)生的原因:
register = memory(g_i);
register = r ...

謝謝你,井蛙夏蟲!
你的意思是說 前++/--這種操作被打斷導(dǎo)致上面的情況。可是我不是太明白,請原諒我的愚昧
printf ++g_i 的時候,打印的就是 g_i 所在內(nèi)存的值,即:
in thread 3075713856 g_i = 1   此時 g_i 內(nèi)存單元的值為 1
in thread 3075713856 g_i = 2   此時 g_i 內(nèi)存單元的值為 2
in thread 3067321152 g_i = 0   此時線程切換,--g_i 是取g_i內(nèi)存的值然后減1,然后將值壓入printf的函數(shù)棧,怎么就變成0了呢?
in thread 3075713856 g_i = 3
in thread 3067321152 g_i = 1
in thread 3075713856 g_i = 4
期待你的更詳細(xì)的講解。

論壇徽章:
11
技術(shù)圖書徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
4 [報告]
發(fā)表于 2014-04-06 18:44 |只看該作者
2樓都寫明白了吧,++和--都不是atomic操作,為什么還是將--g_i理解為一次執(zhí)行完畢呢?請至少分為三個獨立指令,而且執(zhí)行每個指令后,都可能切換到另外一個線程。
BTW:這算典型的undefined行為,知道不可取就可以了,還深究什么?就好比“malloc一次,free兩次,為什么有時候core,有時不core?”,點到即止。

論壇徽章:
1
巨蟹座
日期:2014-03-18 23:44:30
5 [報告]
發(fā)表于 2014-04-06 21:14 |只看該作者
timespace 發(fā)表于 2014-04-06 18:44
2樓都寫明白了吧,++和--都不是atomic操作,為什么還是將--g_i理解為一次執(zhí)行完畢呢?請至少分為三個獨立指 ...


謝謝指點。
我已知道 ++/-- 不是原子操作,可是我還是不是很明白,能給我做一個深度剖析嗎?
in thread 3075713856 g_i = 1           正常
in thread 3067321152 g_i = 0           正常
in thread 3067321152 g_i = -1           正常
in thread 3075713856 g_i = 1           不正常
in thread 3067321152 g_i = 0           正常
in thread 3075713856 g_i = 1           正常
in thread 3075713856 g_i = 2           正常
in thread 3067321152 g_i = 0           不正常
in thread 3075713856 g_i = 3           不正常
in thread 3067321152 g_i = 1           不正常
in thread 3075713856 g_i = 4           不正常
in thread 3067321152 g_i = 2           不正常
in thread 3075713856 g_i = 5           不正常
in thread 3067321152 g_i = 3           不正常
in thread 3075713856 g_i = 6           不正常
從地一個不正常分析。
在本次打印之前,線程3067321152已將g_i的值修改為-1,然后在本次打印的結(jié)果卻是 1 ,說明本次取到的 g_i 的值為0.   從上面的線程執(zhí)行情況看,只有在第二行的時候值為0,即在線程 3067321152 中。 難道是in thread 3067321152 g_i = -1還沒有及時寫入內(nèi)存,此時發(fā)生線程切換,切換到 in thread 3075713856 g_i = 1,這個時候取到的就是 0
不知道這樣理解對不對。

論壇徽章:
11
技術(shù)圖書徽章
日期:2014-03-01 14:44:34天蝎座
日期:2014-05-21 22:11:59金牛座
日期:2014-05-30 17:06:14
6 [報告]
發(fā)表于 2014-04-06 22:15 |只看該作者
線程棧相互獨立,有各自的寄存器。

/* 從輸出1~4行推斷,第3行輸出之前g_i = 0 ,下面分解第3行和第4行可能執(zhí)行順序 */
t1(++)   r1 = g_i     /* r1是t1的寄存器, g_i = 0那么 r1= 0 */
t2(--)     r2 = g_i     /* r2 = 0 */
t1(++)   r1 += 1     /* r1 = 1 */
t2(--)     r2 -= 1      /* r2 = -1 */
t2(--)     g_i = r2     /* g_i = -1 */
t1(++)   g_i = r1     /* g_i = 1 */
/* 不同步,執(zhí)行是隨機(jī)的,出現(xiàn)其它結(jié)果也不奇怪 */

論壇徽章:
1
巨蟹座
日期:2014-03-18 23:44:30
7 [報告]
發(fā)表于 2014-04-07 00:44 |只看該作者
timespace 發(fā)表于 2014-04-06 22:15
線程棧相互獨立,有各自的寄存器。

/* 從輸出1~4行推斷,第3行輸出之前g_i = 0 ,下面分解第3行和第4行可 ...


恩,看來我在上一樓的理解是對的。
謝謝你這直觀的分析!
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP