線(xiàn)程內(nèi)容:
創(chuàng)新互聯(lián)專(zhuān)注于雞澤企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城網(wǎng)站建設(shè)。雞澤網(wǎng)站建設(shè)公司,為雞澤等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站設(shè)計(jì),專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)
1、如何創(chuàng)建啟動(dòng)一個(gè)線(xiàn)程?
? std::thread定義一個(gè)線(xiàn)程對(duì)象,傳入線(xiàn)程所需的線(xiàn)程函數(shù)和參數(shù),線(xiàn)程自動(dòng)開(kāi)啟
2、子線(xiàn)程如何結(jié)束?
? 子線(xiàn)程函數(shù)運(yùn)行完成,線(xiàn)程就結(jié)束了
3、主線(xiàn)程如何處理子線(xiàn)程
? t.join() : 等待t線(xiàn)程結(jié)束,當(dāng)前線(xiàn)程繼續(xù)往下運(yùn)行
? t.detach() : 把t線(xiàn)程設(shè)置為分離線(xiàn)程,主線(xiàn)程結(jié)束,整個(gè)進(jìn)程結(jié)束,所有子線(xiàn)程都自動(dòng)結(jié)束
#include <thread>
void threadHandler1(int time){
std::this_thread::sleep_for(std::chrono::seconds(time));
std::cout<<"call thread1"<<std::endl;
}
void threadHandler2(int time){
std::this_thread::sleep_for(std::chrono::seconds(time));
std::cout<<"call thread2"<<std::endl;
}
int main(){
std::thread t1(threadHandler1,2);
std::thread t2(threadHandler2,3);
/*t1.join();
t2.join();*/
t1.detach();
t2.join();
std::cout<<"main thread done!"<<std::endl;
return 0;
}
/*
打印輸出:
call thread1
call thread2
main thread done!
*/
上鎖常用lock_guard,他是對(duì)mutex的封裝,出作用域后會(huì)自動(dòng)析構(gòu),析構(gòu)的時(shí)候會(huì)釋放鎖,構(gòu)造函數(shù)會(huì)上鎖
普通的互斥鎖是:
std::mutex mtx;
mtx.lock();
//臨界區(qū)
mtx.unlock();
使用lock_guard是這樣:
{
std::lock_guard<std::mutex> lockGuard(mtx);//出作用域后會(huì)析構(gòu)解鎖,默認(rèn)構(gòu)造是加鎖
//臨界區(qū)
}
互斥鎖的應(yīng)用:
//模擬買(mǎi)票
int ticketCount=;
std::mutex mtx;
void sellTicket(int index){
while(ticketCount>0){//可能會(huì)發(fā)生提前進(jìn)入循環(huán)的情況,所以需要在循環(huán)內(nèi)再加一層判斷
// mtx.lock();
{//
std::lock_guard<std::mutex> lockGuard(mtx);//出作用域后會(huì)析構(gòu)解鎖,默認(rèn)構(gòu)造是加鎖
if(ticketCount>0){
//下面兩句屬于臨界區(qū)代碼,該代碼段中的操作必須是原子操作,要保證線(xiàn)程之間要互斥。
std::cout<<"窗口"<<index<<"賣(mài)出第"<<ticketCount<<"張票"<<std::endl;
ticketCount--;
}
}
// mtx.unlock();
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
int main(){
std::list<std::thread> threadList;
for(int i=1;i<=3;++i){
threadList.push_back(std::thread(sellTicket,i));
}
for(auto &th:threadList){
th.join();
}
std::cout<<"main thread done!"<<std::endl;
return 0;
}
生產(chǎn)者,消費(fèi)者線(xiàn)程模型
C++ STl中的所有容器都不是線(xiàn)程安全的
使用條件變量condition_variable
做線(xiàn)程間的通信操作
線(xiàn)程間同步通信最典型的例子就是生產(chǎn)者-消費(fèi)者模型,生產(chǎn)者線(xiàn)程生產(chǎn)出產(chǎn)品以后,會(huì)通知消費(fèi)者線(xiàn)程去消費(fèi)產(chǎn)品;如果消費(fèi)者線(xiàn)程去消費(fèi)產(chǎn)品,發(fā)現(xiàn)還沒(méi)有產(chǎn)品生產(chǎn)出來(lái),它需要通知生產(chǎn)者線(xiàn)程趕快生產(chǎn)產(chǎn)品,等生產(chǎn)者線(xiàn)程生產(chǎn)出產(chǎn)品以后,消費(fèi)者線(xiàn)程才能繼續(xù)往下執(zhí)行。
C++11 線(xiàn)程庫(kù)提供的條件變量condition_variable,就是Linux平臺(tái)下的Condition Variable機(jī)制,用于解決線(xiàn)程間的同步通信問(wèn)題,下面通過(guò)代碼演示一個(gè)生產(chǎn)者-消費(fèi)者線(xiàn)程模型,仔細(xì)分析代碼:
// 定義互斥鎖(條件變量需要和互斥鎖一起使用)
std::mutex mtx;
// 定義條件變量(用來(lái)做線(xiàn)程間的同步通信)
std::condition_variable cv;
// 定義vector容器,作為生產(chǎn)者和消費(fèi)者共享的容器
std::vector<int> vec;
// 生產(chǎn)者線(xiàn)程函數(shù)
void producer()
{
// 生產(chǎn)者每生產(chǎn)一個(gè),就通知消費(fèi)者消費(fèi)一個(gè)
for (int i = 1; i <= 10; ++i)
{
// 獲取mtx互斥鎖資源
std::unique_lock<std::mutex> lock(mtx);
// 如果容器不為空,代表還有產(chǎn)品未消費(fèi),等待消費(fèi)者線(xiàn)程消費(fèi)完,再生產(chǎn)
while (!vec.empty())
{
// 判斷容器不為空,進(jìn)入等待條件變量的狀態(tài),釋放mtx鎖,
// 讓消費(fèi)者線(xiàn)程搶到鎖能夠去消費(fèi)產(chǎn)品
cv.wait(lock);
}
vec.push_back(i); // 表示生產(chǎn)者生產(chǎn)的產(chǎn)品序號(hào)i
std::cout << "producer生產(chǎn)產(chǎn)品:" << i << std::endl;
/*
* 容器為空,說(shuō)明需要生產(chǎn),生產(chǎn)完對(duì)其他線(xiàn)程進(jìn)行通訊
生產(chǎn)者線(xiàn)程生產(chǎn)完產(chǎn)品,通知等待在cv條件變量上的消費(fèi)者線(xiàn)程,
可以開(kāi)始消費(fèi)產(chǎn)品了,然后釋放鎖mtx
*/
cv.notify_all();
// 生產(chǎn)一個(gè)產(chǎn)品,睡眠100ms
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
// 消費(fèi)者線(xiàn)程函數(shù)
void consumer()
{
// 消費(fèi)者每消費(fèi)一個(gè),就通知生產(chǎn)者生產(chǎn)一個(gè)
for (int i = 1; i <= 10; ++i)
{
// 獲取mtx互斥鎖資源
std::unique_lock<std::mutex> lock(mtx);
// 如果容器為空,代表還有沒(méi)有產(chǎn)品可消費(fèi),等待生產(chǎn)者生產(chǎn),再消費(fèi)
while (vec.empty())
{
// 判斷容器為空,進(jìn)入等待條件變量的狀態(tài),釋放mtx鎖,
// 讓生產(chǎn)者線(xiàn)程搶到鎖能夠去生產(chǎn)產(chǎn)品
cv.wait(lock);//在等待過(guò)程中如果收到信息就會(huì)進(jìn)入阻塞狀態(tài),執(zhí)行下一步操作
}
int data = vec.back(); // 表示消費(fèi)者消費(fèi)的產(chǎn)品序號(hào)i
vec.pop_back();
std::cout << "consumer消費(fèi)產(chǎn)品:" << data << std::endl;
/*
消費(fèi)者消費(fèi)完產(chǎn)品,通知等待在cv條件變量上的生產(chǎn)者線(xiàn)程,
可以開(kāi)始生產(chǎn)產(chǎn)品了,然后釋放鎖mtx
*/
cv.notify_all();
// 消費(fèi)一個(gè)產(chǎn)品,睡眠100ms
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
int main()
{
// 創(chuàng)建生產(chǎn)者和消費(fèi)者線(xiàn)程
std::thread t1(producer);
std::thread t2(consumer);
// main主線(xiàn)程等待所有子線(xiàn)程執(zhí)行完
t1.join();
t2.join();
return 0;
}
互斥鎖只有一個(gè)線(xiàn)程可以拿到,其他線(xiàn)程如果試圖拿到被別的線(xiàn)程占用的互斥鎖的時(shí)候會(huì)進(jìn)入阻塞狀態(tài)
std::lock_guard<std::mutex> lockGuard(mtx);
不能用在函數(shù)參數(shù)傳遞或者返回過(guò)程中,只能用在簡(jiǎn)單的臨界區(qū)代碼段的互斥操作中
unique_lock可以使用在簡(jiǎn)單的臨界區(qū)代碼段的互斥操作中,也可以用在函數(shù)的調(diào)用過(guò)程中:
unque_lock<std::mutex> lck(mtx);
cv.wait(lck);//cv是condition_variable wait方法會(huì)先使線(xiàn)程進(jìn)入等待狀態(tài),然后調(diào)用lck.unlock()方法把mtx釋放掉。
cv.notify_all()
是通知在cv上等待的線(xiàn)程條件成立了該干活了,收到通知的線(xiàn)程會(huì)先從等待狀態(tài)切換到阻塞狀態(tài),如果獲取到互斥鎖那么該線(xiàn)程就會(huì)繼續(xù)執(zhí)行。
首先要包含atomic類(lèi)庫(kù)
一般在++等簡(jiǎn)單操作中使用無(wú)鎖操作(CAS)來(lái)實(shí)現(xiàn)
//原子整型,CAS操作保證給count自增自減的原子操作
std::atomic_int mycount(0);
//線(xiàn)程函數(shù)
void sumTask()
{
//每個(gè)線(xiàn)程給count加1000次
for (int i = 0; i < 1000; ++i)
{
mycount++;
}
}
int main()
{
//創(chuàng)建10個(gè)線(xiàn)程放在容器當(dāng)中
std::vector<std::thread> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(std::thread(sumTask));
}
//等待線(xiàn)程執(zhí)行完成
for (unsigned int i = 0; i < vec.size(); ++i)
{
vec[i].join();
}
//所有子線(xiàn)程運(yùn)行結(jié)束,count的結(jié)果每次運(yùn)行應(yīng)該都是
std::cout << "count : " << mycount << std::endl;
return 0;
}
網(wǎng)站題目:4.c++語(yǔ)言級(jí)別的多線(xiàn)程編程
文章來(lái)源:http://chinadenli.net/article12/dsoipdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、虛擬主機(jī)、服務(wù)器托管、電子商務(wù)、網(wǎng)站排名、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)