偽函數(shù)和多線程
struct func
{
//偽函數(shù)
void operator()() //方法 可以將對象名當作函數(shù)名使用
{
cout << "hello1" << endl;
}
void operator()(int i) //
{
cout << "hello2" <<i<<endl;
}
};
void mainu1()
{
func f1;
f1();
cin.get();
}
//void operator()() 對象名 當作函數(shù)名 重載()
//()僅使用于當前結(jié)構(gòu)體對象
//mystruct()構(gòu)造函數(shù) 創(chuàng)建一個臨時對象 既匿名對象
struct mystruct
{
mystruct()
{
cout << "creat" << endl;
}
~mystruct()
{
cout << "end" << endl;
}
void operator()()
{
MessageBoxA(0,"AABCL","123",0);
}
};
void mainu2()
{
mystruct go1;
thread t1(go1);
mystruct go2;
thread t2(go2);
thread t3(mystruct()); //不適合作為多線程參數(shù) 銷毀太快
//mystruct()構(gòu)造函數(shù) 創(chuàng)建一個臨時對象 既匿名對象
mystruct()();
mystruct*p = new mystruct(); //() 初始化 構(gòu)造函數(shù)
cin.get();
}
成員函數(shù)與多線程
struct funx
{
public:
static void run()
{
MessageBoxA(0, "SSSS", "RRRR", 0);
cout << "hello" << endl;
}
static void runl(const char*str)
{
MessageBoxA(0, str, "RRRR", 0);
cout << "hello" << endl;
}
};
void main()
{
//funx *p(nullptr);
// p->run(); //空類指針可以引用沒有調(diào)用內(nèi)部成員變量的成員函數(shù)
funx fun1;
//&funx::run() 引用成員函數(shù)
thread th1(&funx::run(),fun1);
thread th2(&funx::run(), fun1);
thread th3(&funx::runl(), fun1,"DDD"); //傳遞參數(shù)模式
thread th4(&funx::runl(), fun1,"DDD");
cin.get();
}
多線程通信
#include<future>
#include<string>
#include<cstdlib>
promise<string> val; //全局通信變量
void mainu4()
{
string str1("12345");
string str2("12345");
string str3(str1+str2); //C++風格字符串
//cout << str3 << endl;
thread th1([]()
{
future<string> fu = val.get_future(); //獲取未來的狀態(tài)
cout << "等待中" << endl;
cout << fu.get() << endl;
});
thread th2([]()
{
system("pause");
val.set_value("HHHHHHHHHHHHHHH");
system("pause");
});
th1.join();
th2.join();
cin.get();
}
線程功能擴展基于繼承
class huathread:public thread //C++代碼重用繼承
{
public:
huathread() :thread() //子類調(diào)用父類構(gòu)造函數(shù)
{
}
template <typename T,typename...Args> //子類調(diào)用父類構(gòu)造函數(shù) ,可變參數(shù)的構(gòu)造
huathread(T&& func, Args&&...args): thread( forward<T>(func), forward<Args>(args)... )
{
}
void run(const char*cmd)
{
system(cmd);
}
};
void mainu5()
{
huathread th1([]() {cout << "HHHH" << endl; });
th1.run("calc");
huathread th2([](int num) {cout << "HHHH" << num<<endl; }, 100 );
th2.run("notepad");
cin.get();
}
條件變量
#include<condition_variable>
#include<mutex>
//線程通信 結(jié)合mutex
//一個線程 多個線程處于等待,通知一個或者多個
mutex m; //線程互相排斥
condition_variable cv; //線程通信
void mainu6()
{
thread **ppth = new thread*[10]; //開辟線程指針數(shù)組
for (size_t i = 0; i < 10; i++)
{
ppth[i] = new thread([](int index) {
unique_lock<mutex> lck(m);//鎖定
cv.wait_for(lck,chrono::hours(1000));//一直等待
cout << index << endl; //打印編號
},i); //傳遞參數(shù)
this_thread::sleep_for(chrono::milliseconds(100)); //錯開
}
//for (size_t i = 0; i < 10; i++)
//{
// lock_guard<mutex> lckg(m); //解鎖向?qū)? // //cv.notify_one(); //挨個通知
//}
for (size_t i = 0; i < 10; i++)
{
lock_guard<mutex> lckg(m); //解鎖向?qū)? }
cv.notify_all(); //通知全部
for (size_t i = 0; i < 10; i++)
{
ppth[i]->join();
delete ppth[i];
}
delete[] ppth;
cin.get();
}
并行計算 獲取結(jié)果
#include<future> //線程將來結(jié)果
#include<chrono> //時間
#include<mutex>
mutex g_m;
void mainu7()
{
auto run = [=](int index) ->int
{
lock_guard<mutex> lckg(g_m); //加鎖
cout << this_thread::get_id() <<" "<< index << endl; //獲取線程id
this_thread::sleep_for(chrono::seconds(10));
return index * 1024; //返回結(jié)果
};
packaged_task<int(int)> pt1(run);
packaged_task<int(int)> pt2(run); //創(chuàng)建兩個任務(wù)包
thread t1([&]() {pt1(2);});
thread t2([&]() {pt2(3);}); //開啟線程
cout << pt1.get_future().get() << endl;
cout << pt2.get_future().get() << endl; //獲取結(jié)果
t1.join();
t2.join();
cin.get();
}
vector介紹
//vector 動態(tài)數(shù)組 無限嵌套
//增刪查改,動態(tài)的數(shù)據(jù)結(jié)構(gòu) 線性表的順序存儲
void mainu8()
{
//vector<int> myint{ 1,2,3,4,5 };
//
//for (int i = 10; i < 20; i++)
//{
// myint.push_back(i);
//}
//myint.resize(5); //動態(tài)調(diào)整大小
//myint.resize(6,90); //vector 6個數(shù)據(jù) 緩沖90
//cout << myint.front() << endl;
//cout << myint.back() << endl;
//cout << "============================" << endl;
//for (auto i : myint)
//{
// cout << i << endl;
//}
//for (size_t i = 0; i < myint.size(); i++)
//{
// cout << myint[i] <<" "<< myint.at(i) << endl;
//}
////迭代器訪問 本質(zhì)就是指針
//for (auto ib = myint.begin(), ie = myint.end();ib != ie;ib++) //順序
//{
// cout << *ib << endl;
//}
//for (auto rb = myint.rbegin(), re = myint.rend();rb != re;rb++) //逆序
//{
// cout << *rb << endl;
//}
vector<int> myintx{ 11,12,13,14,15 };
vector<int> myint1{ 1,2,3,4,5 };
//myint1.assign(7,100); //重新初始化
auto it = myint1.begin() + 3;
int a[5]{ 21,22,23,24,25 };
//it = myint1.insert(it,400); //根據(jù)位置插入
//cout << "*it:" << *it << endl;
//it = myint1.insert(it, a, a + 5); //插入一個數(shù)組
//it = myint1.insert(it,myintx.begin(),myintx.end()); //批量插入
//myint1.erase(it);
myint1.erase(myint1.begin(),myint1.begin()+3); //批量刪除 不包含最后一個
vector<int> myint2{ 1,2,3,4,5 };
vector<int> myint3{ 31,32,33,34,35 }; //堆上 不會棧溢出
myint2.swap(myint3);
//for (auto i : myint2)
//{
// cout << i << endl;
//}
//for (int i = 0; i < 5; i++) //內(nèi)存是連續(xù)的
//{
// cout << myint2[i] << " " << &myint2[i] << endl;
//}
vector<int> myint;
int*p = myint.get_allocator().allocate(5); //獲取分配器分配內(nèi)存
cout << myint.size() << endl << endl << endl;
for (size_t i = 0; i < 5; i++)
{
// cout << (p[i] = i) << endl;
}
myint.get_allocator().deallocate(p,5); //釋放內(nèi)存
vector<int> myintx1{ 1,2,3,4,5 };
vector<int> myintx2{ 21,2,3,4,5 ,6,7};
vector<int> myintx3{ 1,2,3 };
vector< vector<int> > myallintx{ myintx1,myintx2,myintx3 };
for (auto i : myallintx)
{
for (auto j : i)
{
cout << j << " ";
}
cout << endl;
}
cin.get();
}
可變參數(shù)與多線程
#include<cstdarg>
//可變參數(shù)
int go(const char*fmt, ...)
{
va_list ap; //指針
va_start(ap, fmt); //開始
vprintf(fmt,ap); //調(diào)用
va_end(ap); //結(jié)束
return 0;
}
void mainu9()
{
thread th(go, "%sABCD%d______%c_____%x", "12345as", 98, 'c', 256);
cin.get();
}
并行計算結(jié)果匯總
#include<future>
#include<vector>
#include<cstdlib>
#define COUNT 5000000
int add(vector<int>*arr,int start,int count)
{
static mutex m;//只會初始化一次
int sum(0);
for (int i = 0; i < count; i++)
{
sum += (*arr)[start + i];//實現(xiàn)累加
}
{
//顯示結(jié)果必須 僅僅計算多余 加鎖
lock_guard<mutex> lckg(m); //鎖定
cout << " thread:" << this_thread::get_id()
<< " count=" << count
<< " sum=" << sum << endl; //打印結(jié)果
}
return sum;
}
void mainu10()
{
vector<int> data(COUNT); //數(shù)組
for (int i = 0; i < COUNT; i++)
{
data[i] = (i + 1) % 1000; //0-999
}
vector<future<int> > result; //結(jié)果數(shù)組
int cpus = thread::hardware_concurrency(); //CPU核心個數(shù)
for (int i = 0; i < cpus*2; i++) //4核CPU 總共創(chuàng)建8個線程任務(wù)
{
//線程任務(wù)分割
int batch_each = COUNT / (cpus * 2);
if (i == (cpus * 2) - 1)
{
batch_each=COUNT- COUNT / (cpus * 2)*i; //最后一個線程 承擔多點
}
//不斷壓入結(jié)果
result.push_back( async(add, &data, i*batch_each,batch_each) ); //
//async返回結(jié)果
}
//匯總
int lastresult(0);
for (int i = 0; i < cpus * 2; i++)
{
lastresult += result[i].get(); //匯總結(jié)果
}
cout << "lastresult= " << lastresult << endl;
cin.get();
}
死鎖與解鎖
#include<mutex>
#define COUNT1 1000000
mutex g_mutex1, g_mutex2; //互斥量
void add1(int*p1,int*p2)
{
for (int i = 0; i < COUNT1; i++)
{
g_mutex1.lock();
(*p1)++;
g_mutex1.unlock();
g_mutex2.lock();
(*p2)++;
g_mutex2.unlock();
}
}
void add2(int*p1, int*p2)
{
for (int i = 0; i < COUNT1; i++)
{
g_mutex2.lock();
(*p2)++;
g_mutex2.unlock();
g_mutex1.lock();
(*p1)++;
g_mutex1.unlock();
}
}
//thread 引用類型函數(shù) 模板 避免類型轉(zhuǎn)換 盡量指針 少使用引用
//鎖住一個變量 盡快操作完解鎖 不要再鎖其他變量 否則互鎖
void mainu11()
{
int a = 0;
int b = 0;
thread th1(add1, &a, &b);
thread th2(add2, &a, &b);
th1.join();
th2.join();
while (1)
{
cout << a << endl;
cout << b << endl;
this_thread::sleep_for(chrono::seconds(3));
}
cin.get();
}
迅雷線程面試題與線程交換與移動
題目:
//編寫一個程序 開啟3個線程 這3個線程ID分別為A B C
//每個線程將自己ID在屏幕上打印10遍
//要求輸出結(jié)構(gòu)必須按ABC順序顯示: 如ABCABC.....以此類推
#include<condition_variable>
#include<mutex>
#include<thread>
int Loop = 10;
int flag = 0;
mutex m;
condition_variable cv;
void fun(int id)
{
for (int i = 0; i < Loop; i++)
{
unique_lock<mutex> ulk(m); //設(shè)定鎖定
while ((id-65)!=flag)
{
cv.wait(ulk); //不是該出現(xiàn)的場合 等著
}
cout << (char)id << endl;//轉(zhuǎn)換
flag = (flag + 1) % 4;// 012
cv.notify_all(); //通知全部
}
}
void mainu12()
{
thread t1(fun,65);
thread t2(fun, 66);
thread t3(fun, 67);
thread t4(fun, 68);
t1.join();
t2.join();
t3.join();
t4.join();
cin.get();
}
線程交換與移動
void mainu13()
{
//thread t1([]() {cout << "FFFFFFF" << endl;});
//thread t2([]() {cout << "HHHHHHH" << endl;});
//cout << "t1 id:" <<t1.get_id() << endl<<"t2 id:" << t2.get_id() << endl;
//swap(t1,t2);
//cout << "t1 id:" << t1.get_id() << endl << "t2 id:" << t2.get_id() << endl;
//t1.join();
//t2.join();
thread t1([]() {
int i = 0;
while (1)
{
i++;
if (i > 100000000) break;
}
cout << i << endl;
system("pause");
});
//t1.join();
cout << t1.get_id() << endl;
thread t2 = move(t1); //線程移動 t2具備t1的屬性
cout << t1.get_id() << endl;
cout << t2.get_id() << endl;
t2.join();
cin.get();
}
unique_lock與lock_guard
#include<mutex>
mutex g_mutex; //全局互斥量
#define N 1000000
void add(int*p)
{
for (int i = 0; i < N; i++)
{
unique_lock<mutex>ulk(g_mutex);// 自動加鎖 自動解鎖 根據(jù)塊語句鎖定
//根據(jù)mutex屬性 是否可以加鎖
lock_guard<mutex>lgd(g_mutex); //擁有mutex所有權(quán) 鎖定向?qū)? 自動加鎖 自動解鎖
//讀取失敗的情況下就一直等待
(*p)++;
}
}
void mainu14()
{
int a = 0;
thread t1(add,&a);
thread t2(add, &a);
t1.join();
t2.join();
cout << a << endl;
cin.get();
}
等待固定時間
#include<chrono>
#include<condition_variable>
#include<mutex>
#include<ctime>
condition_variable cv;
mutex m;
bool done=false;
void run()
{
auto start = chrono::high_resolution_clock::now(); //當前時間
auto end =start + chrono::seconds(10);
unique_lock<mutex> lk(m);
while (!done)
{
if (cv.wait_until(lk, end) == cv_status::timeout) //超過時間
{
done = true;
break;
}
}
//this_thread::sleep_until(end);
system("pause");
}
void mainu15()
{
//thread t1(run);
time_t t1, t2;
auto start = chrono::high_resolution_clock::now(); //當前時間
t1 = time(&t1);
double db = 0;
for (int i = 0; i < 10000000; i++)
{
db += i;
}
t2 = time(&t2);
auto end = start + chrono::milliseconds(5000);
cout <<(end - start).count() << endl; //精確度高
cout << difftime(t2 , t1) << endl; //精確度低
//this_thread::sleep_until(end); //線程等待不用sleep_until
cin.get();
}
生產(chǎn)者 消費者
//生產(chǎn)不允許讀取 讀取不允許生產(chǎn)
#include<vector>
#include<array>
#include<mutex>
#include<condition_variable>
mutex m;
condition_variable isfull, isempty; //處理兩種情況
bool flag = true; //標志 消費完了退出
vector<int> myint;
void put(int num) //生產(chǎn)者
{
for (int i = 0; i < num; i++)
{
unique_lock<mutex> lk(m);//鎖定
while (myint.size()>=10)
{
isempty.wait(lk); //滿了一直等待
}
myint.push_back(i);//插入
cout << "生產(chǎn)" << i << endl;
isfull.notify_all(); //通知消費者
}
this_thread::sleep_for(chrono::seconds(5)); //休眠
flag = false;
}
void take() //消費者
{
while (flag)
{
unique_lock<mutex> lk(m);//鎖定
while (myint.size()==0)
{
isfull.wait(lk); //等待
}
if(flag)
{
cout <<"消費:"<< myint[myint.size() - 1] << " "<<this_thread::get_id() <<endl;
myint.pop_back(); //消除
isempty.notify_all(); //通知生產(chǎn)者
}
}
}
void main()
{
vector<int> myint{ 1,2,3,4,5 };
myint.pop_back(); //刪除尾部
myint.push_back(19);
for (auto i: myint)
{
cout << i << endl;
}
thread t1(take);
thread t2(take);
thread t3(take);
put(100);
thread s1(put,15);
thread s2(put,10);
t1.join();
t2.join();
t3.join();
cin.get();
}