9 C++ Boost 多线程,线程同步

线程的创建 boost_thread,boost_system
多线程的创建
线程的参数传递
线程的创建方式
线程的join
加入join,回收线程

线程中断
线程中断2,
线程组
boost 线程的死锁
boost 线程递归锁
线程互斥锁,线程同步
unique_lock 锁,离开作用域自动释放
unique_lock 锁 示例 2,可以显式的释放锁
boost 1次初始化
boost 条件变量
boost 线程锁,一个账户往另外一个账户转钱案例
boost upgrade_lock

知识背景:

理解什么是线程,什么是进程,区别是什么,如何使用多进程多线程

线程的创建 boost_thread,boost_system

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;

void fun()
{
	cout << "Hello Boost threads !" << endl;
}

int main() 
{
	boost::thread t1(fun);
	t1.join();

	return 0;
}
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
Hello Boost threads !
[email protected]:~/boost$

多线程的创建

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;

void fun1(){cout << "Hello Boost threads 1!" << endl;}
void fun2(){cout << "Hello Boost threads 2!" << endl;}
void fun3(){cout << "Hello Boost threads 3!" << endl;}

int main() 
{
	boost::thread t1(fun1);	t1.join();
	boost::thread t2(fun2);	t2.join();
	boost::thread t3(fun3);	t3.join();

	return 0;
}
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
Hello Boost threads 1!
Hello Boost threads 2!
Hello Boost threads 3!
[email protected]:~/boost$


线程的参数传递

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
void fun1(const int &id){cout << "threads id "<<id << endl;}
void fun2(const int &id){cout << "threads id "<<id << endl;}
void fun3(const int &id){cout << "threads id "<<id << endl;}
int main() 
{
	boost::thread t1(fun1,1);	t1.join();
	boost::thread t2(fun2,2);	t2.join();
	boost::thread t3(fun3,3);	t3.join();

	return 0;
}
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
threads id 1
threads id 2
threads id 3
[email protected]:~/boost$


线程的创建方式

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;

void fun1(const int &id)
{
	cout << "threads id "<<id << endl;
}

struct MyThread
{
	void operator()(const int &id)
	{
		cout << "threads id "<<id << endl;
	}
	void fun(const int &id)
	{
		cout << "threads id "<<id << endl;
	}
};

int main() 
{
	boost::thread t1(fun1,1);//自由函数
	t1.join();

	MyThread mythread;
	boost::thread t2(mythread,2);//函数对象   
	t2.join();

	boost::thread t3(&MyThread::fun,mythread,3); //成员函数  
	t3.join();

	boost::thread t4(MyThread(),4);	//临时对象
	t4.join();

	boost::thread t5(boost::ref(mythread),5);//对象引用
	t5.join();
	return 0;
}
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
threads id 1
threads id 2
threads id 3
threads id 4
threads id 5
[email protected]:~/boost$



线程的join

chunli[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;

void fun1(const int &id){cout << "threads id "<<id << endl;}

int main() 
{
	boost::thread t1(fun1,1);
	//t1.join();
	cout << "main end!" << endl;
	return 0;
}
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
main end!
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
main end!threads id 1

[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
main end!
threads id 1
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
main end!
threads id [email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
main end!
threads id 1
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
main end!
threads id 1
[email protected]:~/boost$ 
可以看出,如果没有join的等待,结果是不可预期的.


加入join,回收线程

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;

void fun1(const int &id){cout << "threads id "<<id << endl;}

int main() 
{
	boost::thread t1(fun1,1);
	t1.join();
	cout << "main end!" << endl;
	return 0;
}
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
threads id 1
main end!
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
threads id 1
main end!
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
threads id 1
main end!
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
threads id 1
main end!
[email protected]:~/boost$

线程中断

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
using boost::thread;

void f1(const int& id) 
{
	cout << "thread #" << id << ": started" << endl;
	boost::system_time const timeout = boost::get_system_time()+ boost::posix_time::seconds(3);
	thread::sleep(timeout);//sleep不会放弃时间片
	cout << "thread #" << id << ": ended" << endl;
}

void f2(const int& id) 
{
	cout << "thread #" << id << ": started" << endl;
	thread::yield();//预定义中断点.主动放弃时间片
	cout << "thread #" << id << ": ended" << endl;
}

void f3(const int& id) 
{
	cout << "thread #" << id << ": started" << endl;
	boost::this_thread::interruption_point();//预定义中断点
	cout << "thread #" << id << ": ended" << endl;
}

int main() 
{
	thread t1(f1, 1);	t1.interrupt();
	thread t2(f2, 2);
	thread t3(f3, 3);	t3.interrupt();

	t1.join();
	t2.join();
	t3.join();
}

[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
thread #2: started
thread #1: started
thread #3: started
thread #2: ended
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
thread #1: started
thread #3: started
thread #2: started
thread #2: ended
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
thread #thread #2: started1: started
thread #3: started

thread #2: ended
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
thread #3: started
thread #1: started
thread #2: started
thread #2: ended
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
thread #2: started
thread #3: started
thread #thread #2: ended
1: started
[email protected]:~/boost$ 
只有2线程不会被打断


线程中断2,

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
using boost::thread;

void print(const int& id) 
{
	boost::this_thread::disable_interruption di;//创建一个不可被打断的对象
	cout << boost::this_thread::interruption_enabled() << endl;
	cout << "thread #" << id << ": ";
	//boost::this_thread::sleep(boost::posix_time::seconds(2));
	boost::system_time const timeout = boost::get_system_time() + boost::posix_time::seconds(2);
	thread::sleep(timeout);

	for (int i = 1; i < 11; ++i)
	{
		cout << i << ‘ ‘;
	}
	cout << endl;

	boost::this_thread::restore_interruption ri(di);//到这里,对象不可被打断
	cout << boost::this_thread::interruption_enabled() << endl;
	//实际上,是可以被打断
}

int main() 
{
	//线程还没有运行结束,叫被打断
	thread t1(print, 1);
	thread t2(print, 2);
	thread t3(print, 3);	t3.interrupt();

	t1.join();
	t2.join();
	t3.join();
}

[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
0
thread #1: 0
thread #3: 0
thread #2: 1 2 3 4 5 6 7 8 9 10 
1
1 2 3 4 5 6 7 8 9 10 
1
1 2 3 4 5 6 7 8 9 10 
1
[email protected]:~/boost$ g++ main.cpp -l boost_thread -l boost_system && ./a.out 
0
thread #1: 0
thread #2: 0
thread #3: 1 2 3 4 5 6 7 8 9 10 
1
1 2 3 4 5 6 7 8 9 10 
1
1 2 3 4 5 6 7 8 9 10 
1
[email protected]:~/boost$



线程组

[email protected]:~/桌面/qt_pro/01/untitled$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
using boost::thread;
void f1(){    cout << "fun1 " << endl;}
void f2(){    cout << "fun2 " << endl;}

int main()
{
    boost::thread_group group;
    for(int i = 0;i<3;++i)
    {
        group.create_thread(f1);
    }
    group.add_thread(new boost::thread(f2));
    cout<<group.size()<<endl;
    group.join_all();
}

[email protected]:~/桌面/qt_pro/01/untitled$ g++ main.cpp -lboost_thread -lboost_system -Wall && ./a.out 
fun1 4
fun1 
fun2 
fun1 

[email protected]:~/桌面/qt_pro/01/untitled$ g++ main.cpp -lboost_thread -lboost_system -Wall && ./a.out 
fun1 
fun1 
fun1 
4
fun2 
[email protected]:~/桌面/qt_pro/01/untitled$


boost 线程的死锁

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
using boost::thread;

boost::mutex m;

void function1()
{
    m.lock();
    cout << "function 1 \n";
    m.unlock();
}

void function2()
{
    m.lock();
    cout << "function 2 \n";
    function1();
    m.unlock();
}

int main()
{
    thread t1(function1);   t1.join();
    thread t2(function2);   t2.join();
}

[email protected]:~/boost$ g++ main.cpp -lboost_thread -lboost_system&& ./a.out 
function 1 
function 2 
^C
[email protected]:~/boost$



boost 线程递归锁

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
using boost::thread;

boost::recursive_mutex m;

void function1()
{
    m.lock();
    cout << "function 1 \n";
    m.unlock();
}

void function2()
{
    m.lock();
    cout << "function 2 \n";
    function1();
    m.unlock();
}

int main()
{
    thread t1(function1);   t1.join();
    thread t2(function2);   t2.join();
}

[email protected]:~/boost$ g++ main.cpp -lboost_thread -lboost_system -lpthread && ./a.out 
function 1 
function 2 
function 1 
[email protected]:~/boost$


线程互斥锁,线程同步

boost::mutex m;

void function1(int id)
{
    m.lock();
    cout <<"thread #"<<id<<":";
    for(int i=0;i<15;i++)
        cout << i<<‘ ‘;
    cout << endl;
    m.unlock();
}

int main()
{
    thread t1(function1,1);   t1.join();
    thread t2(function1,2);   t2.join();
    thread t3(function1,3);   t3.join();
    thread t4(function1,4);   t4.join();
    thread t5(function1,5);   t5.join();
    thread t6(function1,6);   t6.join();

}

[email protected]:~/boost$ g++ main.cpp -lboost_thread -lboost_system -lpthread && ./a.out 
thread #1:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
thread #2:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
thread #3:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
thread #4:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
thread #5:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
thread #6:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
[email protected]:~/boost$


unique_lock 锁,离开作用域自动释放

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <list>

#include <boost/thread.hpp>
using namespace std;
using boost::thread;

boost::mutex m;
int k = 0;

void decrement()
{
    boost::unique_lock<boost::mutex> lock(m);
    for(int i = 0;i<=100;++i)
    {
        k-=i;
    }
    cout << "after decrement k="<<k << endl;
}

void increment()
{
    boost::unique_lock<boost::mutex> lock(m);
    for(int i = 0;i<=100;++i)
    {
        k+=i;
    }
    cout << "after increment k="<<k << endl;
}

int main()
{
    boost::thread t1(increment);    t1.join();
    boost::thread t2(decrement);    t2.join();

}

[email protected]:~/boost$ g++ main.cpp -lboost_thread -lboost_system -lpthread && ./a.out 
after increment k=5050
after decrement k=0
[email protected]:~/boost$


unique_lock 锁 示例 2,可以显式的释放锁

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <vector>
#include <boost/thread.hpp>
using namespace std;
using boost::thread;

boost::mutex m;

void updateString()
{
    boost::unique_lock<boost::mutex> lock(m);//lock
    lock.unlock();//unlock
    lock.lock();
}

int main()
{
    thread t1(updateString);    t1.join();
    thread t2(updateString);    t2.join();
}

[email protected]:~/boost$ g++ main.cpp -lboost_thread -lboost_system -lpthread && ./a.out 
[email protected]:~/boost$



boost 1次初始化


[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>

using namespace std;
using boost::thread;
boost::once_flag once = BOOST_ONCE_INIT; // 注意这个操作不要遗漏了
void func() {
	cout << "Will be called but one time!" << endl;
}
void threadFunc() {
	//    func();
	boost::call_once(&func, once);
}

int main() {
	boost::thread_group threads;
	for (int i = 0; i < 5; ++i)
		threads.create_thread(&threadFunc);
	threads.join_all();
}

[email protected]:~/boost$ g++ main.cpp  -lboost_thread -lboost_system && ./a.out 
Will be called but one time!
[email protected]:~/boost$



boost 条件变量

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>
using namespace std;
using boost::thread;

boost::condition_variable cond; // 关联多个线程的条件变量
boost::mutex m; // 保护共享资源 k 的互斥体
int k = 0; // 共享资源

void f1(const int& id) 
{
	boost::unique_lock<boost::mutex> lock(m);
	while (k < 5) 
	{
		cout << "thread #" << id << ": k < 5, waiting ..." << endl;
		cond.wait(lock); // #1
	}
	cout << "thread #" << id << ": now k >= 5, printing ..." << endl;
}

void f2(const int& id) 
{

	boost::unique_lock<boost::mutex> lock(m);
	cout << "thread #" << id << ": k will be changed ..." << endl;
	k += 5;
	cond.notify_all(); // #2 不需lock
}

int main() {
	// 如果f2()中是 cond.notify_one(),结果?
	boost::thread t1(f1, 1);
	boost::thread t2(f1, 2);
	boost::thread t3(f2, 100);

	t1.join();
	t2.join();
	t3.join();
}

[email protected]:~/boost$ g++ main.cpp  -lboost_thread -lboost_system && ./a.out 
thread #1: k < 5, waiting ...
thread #2: k < 5, waiting ...
thread #100: k will be changed ...
thread #1: now k >= 5, printing ...
thread #2: now k >= 5, printing ...
[email protected]:~/boost$


boost 线程锁,一个账户往另外一个账户转钱案例

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>

using namespace std;
using boost::thread;

class Account {
	boost::mutex m;
	double balance;
	public:
	Account() :
		balance() {
		}

	Account(const double& bal) :
		balance(bal) {
		}

	double getBalance() const {
		return balance;
	}

	friend void transfer(Account& from, Account& to, double amount);
};

//// version 3: OK (使用lock() 和 unique_lock)
//void transfer(Account& from, Account& to, double amount) {
//    boost::lock(from.m, to.m);
//    boost::unique_lock<boost::mutex> lockFrom(from.m, boost::adopt_lock);
//    boost::unique_lock<boost::mutex> lockTo(to.m, boost::adopt_lock);
//
//    from.balance -= amount;
//    to.balance += amount;
//}

// version 2: OK (使用lock() 和 lock_guard)
void transfer(Account& from, Account& to, double amount) {
	boost::lock(from.m, to.m);
	boost::lock_guard<boost::mutex> lockFrom(from.m, boost::adopt_lock);
	boost::this_thread::sleep(boost::posix_time::seconds(1));
	boost::lock_guard<boost::mutex> lockTo(to.m, boost::adopt_lock);
	from.balance -= amount;
	to.balance += amount;
}

// version 1: 可能造成死锁
//void transfer(Account& from, Account& to, double amount) {
//    boost::lock_guard<boost::mutex> lockFrom(from.m); // #1
//    boost::this_thread::sleep(boost::posix_time::seconds(1));
//    boost::lock_guard<boost::mutex> lockTo(to.m); // #2
//    from.balance -= amount;
//    to.balance += amount;
//}

int main() {
	Account a1(1200.00);
	Account a2(300.00);

	boost::thread t1(transfer, boost::ref(a1), boost::ref(a2), 134.85);
	boost::thread t2(transfer, boost::ref(a2), boost::ref(a1), 100.30);
	t1.join();
	t2.join();

	cout << "Balance of a1: " << a1.getBalance() << endl;
	cout << "Balance of a2: " << a2.getBalance() << endl;
}

[email protected]:~/boost$ g++ main.cpp  -lboost_thread -lboost_system -lpthread && ./a.out 
Balance of a1: 1165.45
Balance of a2: 334.55
[email protected]:~/boost$



boost upgrade_lock

[email protected]:~/boost$ cat main.cpp 
#include <iostream>
#include <boost/thread.hpp>

using namespace std;
using boost::thread;
boost::shared_mutex m;
int k = 1;

void f(int id) {
	boost::upgrade_lock<boost::shared_mutex> lock(m);
	cout << "thread #" << id << ": " << k << endl;
	if (k < 6) {
		// boost::unique_lock<boost::shared_mutex> lock2(boost::move(lock)); // alternate:
		boost::upgrade_to_unique_lock<boost::shared_mutex> lock2(lock);
		k += 3;
	}
}

int main() {
	boost::thread t1(f, 1);
	boost::thread t2(f, 2);
	boost::thread t3(f, 3);

	t1.join();
	t2.join();
	t3.join();
}

[email protected]:~/boost$ g++ main.cpp  -lboost_thread -lboost_system -lpthread && ./a.out 
thread #2: 1
thread #1: 4
thread #3: 7
[email protected]:~/boost$
时间: 2024-10-18 00:02:10

9 C++ Boost 多线程,线程同步的相关文章

Unix C++(boost) 线程同步和线程组

#include <boost/thread.hpp> #include <iostream> #include <vector> #include <cstdlib> #include <ctime> boost::mutex mutex; boost::condition_variable_any cond; std::vector<int> random_numbers; void fill() { std::srand(sta

多线程&线程同步

线程 程序执行过程中,并发执行的代码段. 线程之间可以共享内存. 线程安全 增加了同步处理,确保在同一时刻,只有一个线程执行同步代码. 保证线程安全的方法就是锁机制 java中的任何对象都可以作为锁对象 synchronized(lock){....} 代码块中的代码被确保同一时间只有一个线程才能执行 同步方法是用当前对象作为同步对象(this) public synchronized int getTicket(){...} synchronized关键字也能加在方法上 确保同一时间只有一个线

多线程——线程同步,死锁

线程同步: 为什么需要同步 ①   线程同步是为了防止多个线程访问一个数据对象时,对数据造成破坏. ②   线程的同步是保证多线程安全访问竞争资源的一种手段. 同步和锁 ①   Java中每一个对象都有一个内置锁. ②   当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁:当程序运行到synchronized同步代码块时,自动获得锁定对象的锁. ③   获得一个对象的锁也称为获取锁.锁定对象.在对象上锁定或在对象上同步.当程序运

Java多线程 线程同步

如果你正在写一个变量,它可能接下来将被另一个线程读取,或者正在读取一个上一次已经被另一个线程写过的变量,那么你需要使用同步,并且,读写线程都必须用相同的监视器锁同步.--Brain同步规则 synchronized 所有对象都自动含有单一的锁,当在调用一个对象的任意synchronized方法时,此对象将被加锁. 对于某个特定对象来说,所有的synchronized方法共享同一个锁.所以某个线程在访问对象的一个synchronized方法时,其他线程访问该对象的任何synchronized方法都

Java多线程——线程同步

在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的控制吧. 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问.   一.多线程引起的数据访问安全问题 下面看一个经典的问题,银行取钱的问题: 1).你有一张银行卡,里面有50

JAVA多线程线程同步问题

线程同步 在多线程的编程环境下,可能看着没有问题的代码在运行几千上万或者更多次后,出现了一些看着很奇怪的问题,出现这样的问题的原因就是可能会有两个或者更多个线程进入了同一块业务处理代码中导致了判断失效.为了解决这个问题,JAVA引入了同步监视器来解决这个问题.同步监视器的通用方法就是同步代码块,也就是给一块代码加了同步锁. package cn.test.hf; import java.math.BigDecimal; /** * 模拟取钱操作 */public class RunnableTe

第18章 多线程----线程同步

Java提供了线程同步的机制来防止资源访问的冲突. 1.线程安全 实际开发中,使用多线程程序的情况很多,如银行排号系统.火车站售票系统等.这种多线程的程序通常会发生问题. 以火车站售票系统为例,在代码中判断当前票数是否大于0,如果大于0则执行将该票出售给乘客功能,但当两个线程同时访问这段代码时(假如这时只剩下一张票),第一个线程将票售出,与此同时第二个线程也已经执行完成判断是否有票的操作,并得出结论票数大于0,于是它也执行售出操作,这样就会产生负数.所以在编写多线程程序时,应该考虑到线程安全问题

服务总结 -多线程 - 线程同步(AutoResetEvent与ManualResetEvent)

前言 在我们编写多线程程序时,会遇到这样一个问题:在一个线程处理的过程中,需要等待另一个线程处理的结果才能继续往下执行.比如:有两个线程,一个用来接收Socket数据,另一个用来处理Socket数据,而处理Socket数据的那个线程需要在接收到Socket数据后才能处理运行,就要等待接收线程接收数据.那么处理线程如何等待,接收线程又如何通知处理线程呢? 其中一个比较好的方式就是使用AutoResetEvent/ManualResetEvent 1. AutoResetEvent/ManualRe

【多线程-线程同步】

线程同步:协调多个线程间的并发操作,以获得符合预期的,确定的执行结果,消除多线程应用程序的不确定性. 使用线程的同步:可以保护资源同时只能由一个线程访问,一般采取的措施是获取锁,释放锁.即锁机制:可以协调线程的访问顺序,即某一资源只能先由线程A访问,再由线程B进行访问. class Program { private static Thread subthread ; private static int i; static void Main(string[] args) { subthrea