您的位置:首页 > 编程语言 > C语言/C++

C++11多线程编程

2017-08-15 14:50 337 查看
1. 基本的多线程实现

#include<iostream>
#include<thread>
#include<string>

using namespace std;
class  Factor {
public:
void operator()(string &msg) {
cout << "from t1:" << msg << endl;
msg = "Read http://blog.csdn.net/hutianyou123"; }
};
int main()
{
string s = "http://blog.csdn.net/hutianyou123";
cout << this_thread::get_id() << endl;
std::thread t1((Factor()),move(s));
thread t2 = move(t1);
cout << t2.get_id() << endl;
t2.join();

//thread::hardware_concurrency();
system("pause");
return 0;
}


上述代码实现基本的线程调度,在主线程中调用线程t1,并将t1移动到t2中,这是t1为空。且主函数字符串s是通过传地址的方式给线程t1。

2. 主线程与子线程同步问题

#include<iostream>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>

using namespace std;

class Logfile
{
public:
Logfile() {
f.open("log.txt");
}
void share_print(string msg, int id) {
lock_guard<mutex>locker(m_mutex);//加同步锁
f << msg << ":" << id << endl;
cout << msg << ":" << id << endl;
}
protected:
private:
mutex m_mutex;
ofstream f;
};

void function_1(Logfile &log) {
for (int i = 0; i < 100; i++)
log.share_print("From t1:", i);
}

int main() {
Logfile log;
thread t1(function_1,ref(log));
for (int i = 0; i >-100; i--)
log.share_print("From main:", i);
if(t1.joinable())
t1.join();

system("pause");
return 0;
}


输出结果:



3. 利用unique_lock实现主从线程同步

#include<iostream>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>
#include<windows.h>
using namespace std;

class Logfile
{
once_flag m_flag;
public:
Logfile() {
}
void share_print(string msg, int id) {
call_once(m_flag, [&]() {f.open(("log.txt")); });
unique_lock<mutex>locker(m_mutex,defer_lock);//加同步锁

locker.lock();
cout<< msg << ":" << id << endl;
locker.unlock();
f << msg << ":" << id << endl;
}

private:
mutex m_mutex;
ofstream f;

};

void function_1(Logfile &log) {
for (int i = 0; i < 100; i++)
log.share_print("From t1:", i);
}

int main() {
Logfile log;
thread t1(function_1, ref(log));
for (int i = 0; i > -100; i--) {
log.share_print("From main:", i);

}
if (t1.joinable())
t1.join();

system("pause");
return 0;
}


lock_guard 加锁保护,可以防止上锁的线程崩溃,而不能及时释放锁。而unique_lock可以提供更多的弹性,可以指定代码同步。用lock/unlock可以灵活的控制加锁同步的范围,但会消耗更多的计算机资源。

4. 如何避免死锁

#include<iostream>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>
#include<windows.h>
using namespace std;

class Logfile
{
public:
Logfile() {
f.open("log.txt");
}
void share_print(string msg, int id) {
lock(m_mutex, m_mutex2);//对mutex按照顺序加锁
lock_guard<mutex>locker(m_mutex,adopt_lock);//加同步锁
lock_guard<mutex>locker2(m_mutex2,adopt_lock);//加同步锁
cout<< msg << ":" << id << endl;
}

void share_print2(string msg, int id) {
lock(m_mutex, m_mutex2);
lock_guard<mutex>locker2(m_mutex2,adopt_lock);//加同步锁
lock_guard<mutex>locker(m_mutex,adopt_lock);//加同步锁
cout << msg << ":" << id << endl;
}
private:
mutex m_mutex;
mutex m_mutex2;
ofstream f;

};

void function_1(Logfile &log) {
for (int i = 0; i < 100; i++)
log.share_print("From t1:", i);
}

int main() {
Logfile log;
thread t1(function_1, ref(log));
for (int i = 0; i > -100; i--) {
log.share_print2("From main:", i);

}
if (t1.joinable())
t1.join();

system("pause");
return 0;
}


lock(m_mutex, m_mutex2)有效的避免了死锁的发生,即使t1线程中的调用log.share_print2函数优先对m_mutex2加锁,也是按照lock设定的顺序执行的。

5. 条件变量提高线程效率

#include<iostream>
#include<deque>
#include<string>
#include<thread>
#include<mutex>
#include<fstream>
#include<condition_variable>
using namespace std;
condition_variable cond;
deque<int>q;
mutex mu;

void function_1() {
int count = 10;
while (count > 0) {
unique_lock<mutex>locker(mu);
q.push_front(count);//给队列加锁
locker.unlock();
cond.notify_one();//标注条件变量
this_thread::sleep_for(chrono::seconds(1));//休眠1秒钟
count--;
}

}

void function_2() {
int data = 0;
while (data != 1) {
unique_lock<mutex>locker(mu);//加锁
cond.wait(locker, []() {return !q.empty(); });//当队列为空,线程处于休眠状态
data = q.back();//从队列获取数据
q.pop_back();
locker.unlock();
cout << "to got a value from t1: " << data << endl;
}

}

int main() {
thread t1(function_1);
thread t2(function_2);
t1.detach();//无需等待t1线程运行结束
t2.join();//等待t2线程运行结束
system("pause");
return 0;
}


运行结果:



引入c++条件变量,#include,来控制子线程等待时间,使用condition_variable::wait(),表示等待上一个线程完成。

如有问题,请指教,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: