Linux 多執行緒不同步導致錯誤示例

2021-08-09 10:12:35 字數 3235 閱讀 9375

多個執行緒都可以看到同乙個物件並有對其操作時涉及到同步問題。

不同步現象:

counter.h

#ifndef _counter_h

#define _counter_h

class counter ;

#endif

counter.c

#include "counter.h"

counter::counter()

counter::~counter()

{}int counter::getcnt()

void counter::setcnt(int cnt)

void counter::inccnt()

main.c

#include 

#include

#include "counter.h"

using

namespace

std;

static counter *pcnt = null;

void *threadruna(void *)

cout

<<"a:"

cout

<<"b:"

; return

0;}

[jiang@eb50

44]$ g++ -o main main.c

counter.c -lpthread

[jiang@eb50

44]$ ./main

create

thread-aok!

!!create

thread-bok!

!!start

threadrunb==>

start

threadruna==>

a:10830472

b:11699219

(ctrl+c)

[jiang@eb50

44]$

看到了吧?結果並不是20000000.

多次執行看看:

[jiang@eb50

44]$ ./main

create

thread-aok!

!!create

thread-bok!

!!start

threadrunb==>

start

threadruna==>

a:11059743

b:12086821

[jiang@eb50

44]$ ./main

create

thread-aok!

!!create

thread-bok!

!!start

threadruna==>

start

threadrunb==>

a:10721130

b:12083639

可見由於沒有對counter pcnt指向的物件進行同步,導致結果錯誤.

本例主要用於示範錯誤,關於為什麼錯誤(時序、作業系統排程切換時間片等造成)請參閱其他資料.

如何解決?加鎖.

counter.h

#ifndef _counter_h

#define _counter_h

#include

class counter ;

#endif

counter.c

#include "counter.h"

counter::counter()

counter::~counter()

int counter::getcnt()

void counter::setcnt(int cnt)

void counter::inccnt()

#include 

#include

#include "counter.h"

using

namespace

std;

static counter *pcnt = null;

void *threadruna(void *)

cout

<<"a:"

cout

<<"b:"

; return

0;}

g++ -o main main.c counter.c -lpthread
執行:

[jiang@eb50

44]$ ./main

create

thread-aok!

!!create

thread-bok!

!!start

threadruna==>

start

threadrunb==>

a:18687418

b:20000000

[jiang@eb50

44]$ vi

main.c

[jiang@eb50

44]$ ./main

create

thread-aok!

!!create

thread-bok!

!!start

threadrunb==>

start

threadruna==>

b:17590204

a:20000000

咦,看起來還是不對呀?並不是,這裡是正確的。

有可能存在a或者b先做完inc運算,然後就回先輸出那個時刻的值,然後剩餘的那個把剩下的做完,剛好是20000000.

一定要注意一點,是在inc的時候出現的錯誤,對i加一不是乙個原子操作,可能在i=i+1時進行了多次的時間片切換,導致錯誤.

只需要在i++的時候注意加鎖即可.保證i++是在critical section中,不會存在race condition.

噢,說個題外話:

一條c/c++語句不是原子的,那麼一條彙編語句是原子的嗎?

答案應該是「不是」.

彙編指令也也只是在描述cpu的行為,而沒有具體到每乙個細節步驟。

操作是否是原子的,不是由彙編指令決定的,而是由cpu如何處理這些指令決定的。

執行緒間出現不同步現象

package comm class res class input implements runnable public void run else x x 1 2 class output implements runnable public void run public class inpu...

執行緒間通訊不同步問題模擬

一 點睛 下面兩種情況可造成執行緒間不同步 1 生產者沒生產完,消費者就來消費。2 消費者沒消費完,生產者又來生產,覆蓋了還沒來得及消費的資料。二 class producer implements runnable override public void run catch interrupte...

VDP 時間不同步連線錯誤解決

系統時鐘 system clock 是指當前 linux kernel 中的時鐘,硬體時鐘 real time clock 是儲存在 cmos 裡的時鐘,關機後該時鐘依然執行,由主機板的電池為它供電。硬體時鐘它依照主機板石英晶體振盪器頻率工作,在啟動系統後,系統從該時鐘讀取時間資訊,之後獨立執行。兩...