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(static_cast<unsigned int>(std::time(0)));

for (int i = 0; i < 3; ++i)

{

boost::unique_lock<boost::mutex> lock(mutex);

random_numbers.push_back(std::rand());

cond.notify_all();

cond.wait(mutex);

}

}

void print()

{

std::size_t next_size = 1;

for (int i = 0; i < 3; ++i)

{

boost::unique_lock<boost::mutex> lock(mutex);

while (random_numbers.size() != next_size)

{

cond.wait(mutex);

}

std::cout << random_numbers.back()<<"---" << std::endl;

++next_size;

cond.notify_all();

}

}

int main()

{

boost::thread t1(fill);

boost::thread t2(print);

t1.join();

t2.join();

}

编译后输出:

703604841---

397897602---

2011646528---

这个例子的程序删除了 wait()count() 。线程不用在每个循环迭代中等待一秒,而是尽可能快地执行。此外,没有计算总额;数字完全写入标准输出流。

为确保正确地处理随机数,需要一个允许检查多个线程之间特定条件的条件变量来同步不每个独立的线程。

正如上面所说, fill() 函数用在每个迭代产生一个随机数,然后放在 random_numbers 容器中。 为了防止其他线程同时访问这个容器,就要相应得使用一个排它锁。 不是等待一秒,实际上这个例子却用了一个条件变量。 调用
notify_all() 会唤醒每个哪些正在分别通过调用wait() 等待此通知的线程。

通过查看 print() 函数里的 for 循环,可以看到相同的条件变量被
wait() 函数调用了。 如果这个线程被 notify_all() 唤醒,它就会试图这个互斥量,但只有在
fill() 函数完全释放之后才能成功。

这里的窍门就是调用 wait() 会释放相应的被参数传入的互斥量。 在调用
notify_all()
后, fill() 函数会通过
wait()
相应地释放线程。 然后它会阻止和等待其他的线程调用 notify_all() ,一旦随机数已写入标准输出流,这就会在
print() 里发生。

注意到在 print() 函数里调用 wait() 事实上发生在一个单独
while 循环里。 这样做的目的是为了处理在 print() 函数里第一次调用
wait() 函数之前随机数已经放到容器里。 通过比较 random_numbers 里元素的数目与预期值,发现这成功地处理了把随机数写入到标准输出流。

#include<boost/thread.hpp>

#include<iostream>

using namespace std;

void f1(){

cout<<"f1()"<<endl;

}

void f2(){

cout<<"f2()"<<endl;

}

int main(){

boost::thread_group grp;

for(int i=0;i<3;++i)

{

grp.create_thread(f1);

}

grp.add_thread(new boost::thread(f2));

cout<<grp.size()<<endl;

grp.join_all();

return 1;

}

编译后输出:

4

f1()

f1()

f2()

f1()

这个程序演示了线程组的用法。

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

时间: 2024-10-08 21:38:16

Unix C++(boost) 线程同步和线程组的相关文章

C# 多线程编程第二步——线程同步与线程安全

上一篇博客学习了如何简单的使用多线程.其实普通的多线程确实很简单,但是一个安全的高效的多线程却不那么简单.所以很多时候不正确的使用多线程反倒会影响程序的性能. 下面先看一个例子 : class Program { static int num = 1; static void Main(string[] args) { Stopwatch stopWatch = new Stopwatch(); //开始计时 stopWatch.Start(); ThreadStart threadStart

Java笔记六.线程同步、线程死锁

线程同步.线程死锁 在上一篇文章中,有一个模拟售卖火车票系统,在卖车票的程序代码中,极有可能碰到一种意外,就是同一张票号被打印两次多次,也可能出现打印出0甚至负数的票号.具体表现为:假设tickets的值为1的时候,线程1刚执行完if(tickets>0)这行代码,正准备执行下面的代码,就在这时,操作系统将CPU切换到了线程2上执行,此时tickets的值仍为1,线程2执行完上面两行代码,tickets的值变为0后,CPU又切回到了线程1上执行,线程1不会再执行if(tickets>0)这行代

关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文)

Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享给大家. 一.对于线程同步和同步锁的理解(注:分享了三篇高质量的博客) 以下我精心的挑选了几篇博文,分别是关于对线程同步的理解和如何选择线程锁以及了解线程锁的作用范围. <一>线程同步锁的选择 1. 这里我推荐下Java代码质量改进之:同步对象的选择这篇博文. 2. 以上推荐的博文是以卖火车票为例

Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)

一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会引起此共享资源的不一致性.因此,为避免线程安全问题,应该避免多线程环境下对此共享资源的并发访问. 线程安全问题多是由全局变量和静态变量引起的,当多个线程对共享数据只执行读操作,不执行写操作时,一般是线程安全的:当多个线程都执行写操作时,需要考虑线程同步来解决线程安全问题. 二.线程同步(synchr

说说C# 多线程那些事-线程同步和线程优先级

上个文章分享了一些多线程的一些基础的知识,今天我们继续学习. 努力学习,成为最好的自己. 一.Task类 上次我们说了线程池,线程池的QueueUserWorkItem()方法发起一次异步的线程执行很简单 但是该方法最大的问题是没有一个内建的机制让你知道操作什么时候完成,有没有一个内建的机制在操作完成后获得一个返回值.为此,可以使用System.Threading.Tasks中的Task类. 简单代码实现: using System; using System.Threading.Tasks;

线程同步、线程同步跟Runnable的区别

线程同步:创建多条线程,要一条线程执行完run()方法,下一个线程才能进入run()方法,线程同步就是为了避免同一条件下不允许多条线程同时进入而制造出来的方法. runnable跟同步的区别:runnable在同一条件下可以同时进入多条线程,而同步不行. 例子,售票台有ticket=100张票,每卖一张run(){ticket--;},当买到只剩一张时,这时线程在未执行ticket--:之前延迟,如果用runnable,就有可能其他线程也进入run(),造成卖出负数张票,而用同步一条线程执行完r

Java04 线程同步问题解决——线程锁(同步锁、互斥锁)

目录 [TOC] 写在最前: 可能有误,请大家批评指正 一.线程切换 Java中,如果要实现在一个线程间的线程切换,需要在线程中使用Thread.yield()即可让出CPU时间. 二.线程锁(也叫同步锁.互斥锁) 线程锁可以在有效缩小同步范围的同时,尽可能的保证并发效率 2.1 使用synchronized关键字对方法进行加锁 对整个线程处理加锁(严重影响效率,不常用) 2.1.1 语法 public synchronized void test(){ } 2.1.2 案例 package c

C# 多线程(二) 线程同步基础

本系列的第一篇简单介绍了线程的概念以及对线程的一些简单的操作,从这一篇开始讲解线程同步,线程同步是多线程技术的难点.线程同步基础由以下几个部分内容组成 1.同步要领(Synchronization Essentials) 2.锁(Locking) 3.线程安全(Thread Safety) 4.事件等待句柄(Signaling with Event Wait Handles) 5.同步上下文(Synchronization Contexts) 同步要领(Synchronization Essen

Java之线程,常用方法,线程同步,死锁

1, 线程的概念 进程与线程 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小.(线程是cpu调度的最小单位) 切换而不是同步 一个程序中的方法有几条执行路径, 就有几个线程 Java中线程的生命周期 Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t =