semaphore是系統中的東西,所以不同系統中包含標頭檔案不同,在linux中包含
說明:
int sem_wait(sem_t *sem)
: 等待訊號量》0,訊號量為0表示無可用資源來使用,就要一直等下去,當訊號量》0時,表示有空餘資源可用,那麼就占用乙個資源給當前執行緒用,並將訊號量減一.
int sem_post(sem_t *sem)
: 釋放資源,將訊號量加1,表示有乙個資源空閒.
課件筆記
程式說明:
完成乙個多執行緒demo, 保證三個執行緒執行順序, 即順序列印a,b,c.
#include
#include
#include
#include
using
namespace std;
sem_t firstjobdone;
// c++ 執行緒如果執行成員函式會對this下的成員做乙份拷貝,所以訊號量不能作為 foo 的成員變數。
sem_t secondjobdone;
class
foo:
public std::enable_shared_from_this
void
first()
void
second()
void
third()
std::shared_ptr
get_this()
};intmain()
}; std::thread t1
;// 這裡 &foo::first 是取類foo的成員函式first的位址,其實就相當於把該函式傳入,
// 然後第二個引數是傳入函式first的引數, 類成員函式的第乙個引數是this指標
std::thread t2
; std::thread t3
;// c++ 獲取成員函式指標的指定寫法,並且需要傳入this指標,因為成員函式第乙個引數是this
// std::thread t1; // error
// std::thread t1; // error
t1.join()
; t2.
join()
; t3.
join()
;return0;
}
命令列編譯:
注意:這裡用到了c++11的標準庫,所以要加-std=c++11
這裡用到了多執行緒,所以要加-pthread
g++ -o semaphore_test semaphore_test.cpp -std=c++11 -pthread
./semaphore_test
互斥量的使用可以用 mutex 庫,lock/unlock,lock_guard(自動解鎖,不可以手動lock/unlock),unique_lock(可以手動lock/unlock)給出 leetcode 1195 的解法:
題目描述:
編寫乙個可以從 1 到 n 輸出代表這個數字的字串的程式,但是:
假設有這麼乙個類:
class
fizzbuzz
// constructor
public
void
fizz
(printfizz)
// only output "fizz"
public
void
buzz
(printbuzz)
// only output "buzz"
public
void
fizzbuzz
(printfizzbuzz)
// only output "fizzbuzz"
public
void
number
(printnumber)
// only output the numbers
}
請你實現乙個有四個執行緒的多執行緒版 fizzbuzz, 同乙個 fizzbuzz 例項會被如下四個執行緒使用:
執行緒a將呼叫 fizz() 來判斷是否能被 3 整除,如果可以,則輸出 fizz。
執行緒b將呼叫 buzz() 來判斷是否能被 5 整除,如果可以,則輸出 buzz。
執行緒c將呼叫 fizzbuzz() 來判斷是否同時能被 3 和 5 整除,如果可以,則輸出 fizzbuzz。
執行緒d將呼叫 number() 來實現輸出既不能被 3 整除也不能被 5 整除的數字。
leetcode鏈結
感覺類似於狀態機,通過對相應狀態的訊號量進行置位(加1),從而實現向下一狀態的轉換.**:
#include
#include
#include
using
namespace std;
class
fizzbuzz
// printfizz() outputs "fizz".
void
fizz
(function<
void()
> printfizz)
}// printbuzz() outputs "buzz".
void
buzz
(function<
void()
> printbuzz)
}// printfizzbuzz() outputs "fizzbuzz".
void
fizzbuzz
(function<
void()
> printfizzbuzz)
}// printnumber(x) outputs "x", where x is an integer.
void
number
(function<
void
(int
)> printnumber)
else
if(cur %3==
0)else
if(cur %5==
0)else
}// 以下三個post通過更新sem_fizz等訊號量,調動其他執行緒執行,進而結束所有執行緒
sem_post
(&sem_fizz)
;sem_post
(&sem_buzz)
;sem_post
(&sem_fizz_buzz);}
};intmain
(int argc,
char
** ar**)
; std::function<
void()
> printbuzz =
(); std::function<
void()
> printfizzbuzz =
(); std::function<
void
(int
)> printnum =
(int x)
; std::thread th[4]
; th[0]
= std::
thread
(&fizzbuzz::fizz,
&fizzbuzz, printfizz)
; th[1]
= std::
thread
(&fizzbuzz::buzz,
&fizzbuzz, printbuzz)
; th[2]
= std::
thread
(&fizzbuzz::fizzbuzz,
&fizzbuzz, printfizzbuzz)
; th[3]
= std::
thread
(&fizzbuzz::number,
&fizzbuzz, printnum)
;for
(auto
&ts : th)
return0;
}
Linux下的訊號量
linux下的訊號量本身就是臨界資源,所以pv操作都是原子操作。下面是實現二元訊號量的 二元訊號量就是互斥鎖。訊號量 中的semop函式是進行pv操作的核心函式,semop的函式原型為 int semop int semid,struct sembuf sops,unsigned nsops 第乙個...
linux下訊號量詳解
訊號量 訊號量實際上就是乙個計數器,用於控制程序或執行緒對臨界資源的同步與互斥,對訊號量的操作是乙個原子操作 也就是在乙個程序或執行緒訪問它時,其它的程序或執行緒不能同時訪問它來打斷前乙個程序或執行緒的操作 它的原理就是在乙個程序或執行緒過來時,先訪問訊號量,如果這個訊號量大於0,則讓計數 1,然後...
訊號量 二值訊號量
訊號量 二值訊號量 訊號量是作業系統的重要部分,訊號量一般用來進行資源管理和任務同步。freertos中訊號量分為二值訊號量 互斥訊號量 計數訊號量和遞迴互斥訊號量,應用場景各不同。二值訊號量通常用於互斥訪問或同步,二值訊號量和互斥訊號量非常相似,但互斥訊號量有優先順序,二值訊號量沒有。因此二值訊號...