Dec 22, 2010

threads and boost.thread

Threads 的优点:
1. 在多CPU或多核系统中,多个线程是真正的同时执行
2. 即使单核系统,线程创建一个工作进程,可以使得主进程响应输入,不会冻结主进程

boost.thread
创建 thread 很灵活,只需要是一个 callable, copyable object
函数
functor

同步
a.join 当前 thread sleep,等待 a 结束
mutex

资源:
多个线程操作的同一个资源
cout cin 也是

rand 在不同线程里面是独立的。
为了有所区别,一种方式是给予不同的seed
另一种办法是定义 Rand class

#include <queue>
#include <string>
#include <cstdlib>
#include <windows.h>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
using namespace std;
using namespace boost;

priority_queue<string> qdl;
mutex mu;
mutex mu_cout;

class Randint
{
public:
 Randint():sd(71) {}
 int get(int maxint);
private:
 int sd;
};

int Randint::get(int maxint)
{
 srand(sd);
 int tmp = rand();
 sd = tmp+197;
 return tmp%(maxint+1);
}


Randint ri;

void adownload(string id)
{
 while(true)
 {
  string url;
  int tt;
  mu.lock();
  if(!qdl.empty())
  {
   url = qdl.top();
   qdl.pop();
  }
  mu.unlock();

  if(!url.empty())
  {
   tt = ri.get(5) + 1;
  }
  else
   break;

  mu_cout.lock();
  cout << id << " start download " << url << ": need " << lexical_cast<string>(tt) << " seconds" << endl;
  mu_cout.unlock();

  Sleep(tt*1000);

  mu_cout.lock();
  cout << id << " finish download " << url << endl;
  mu_cout.unlock();
 }
}

void download()
{
 mu.lock();

 string url;
 int tt;
 if(!qdl.empty())
 {
  url = qdl.top();
  qdl.pop();
  tt = ri.get(5) + 1;
 }
 mu.unlock();


 if(!url.empty())
 {
  mu_cout.lock();
  cout << "start download " << url << ": need " << lexical_cast<string>(tt) << " seconds" << endl;
  mu_cout.unlock();

  Sleep(tt*1000);

  mu_cout.lock();
  cout << "finish download " << url << endl;
  mu_cout.unlock();
 }

}

int main()
{
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));
 qdl.push(string("file")+lexical_cast<string>(ri.get(100)));


 thread tdl1(adownload, string("d1"));
 thread tdl2(adownload, string("d2"));

 tdl1.join();
 tdl2.join();

 return 0;
}

0 comments: