Thread Creation
boost::thread는 std::fstream 클래스가 파일을 표현하는 것과 같은 방식으로 스레드의 실행을 표현한다. Default 생성자가 현재의 실행 스레드를 나타내는 객체를 생성한다. 오버로딩된 생성자는 입력 변수가 없고 리턴하는 것이 없는 함수 객체를 받는다. 이 생성자는 새로운 실행 스레드를 시작하는데 이는 결국 함수 객체의 호출이며 해당 함수의 호출이다.#include <boost/thread/thread.hpp> #include <iostream>void hello() { std::cout << "Hello world, I'm a thread!" << std::endl; } int main(int argc, char* argv[]) { boost::thread thrd(&hello); thrd.join(); return 0; }
Mutexes
- 다른 스레드가 뮤텍스를 잠그지 않을때까지 대기
- 만약 다른 스레드가 뮤텍스를 잠궈놓은 상태라면 바로 리턴하기
- 다른 스레드가 뮤텍스를 잠그지 않을때까지 대기 하거나 혹은 일정 시간만 대기 하다가 리턴
#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <iostream>boost::mutex io_mutex;
struct count { count(int id) : id(id) { }
void operator()() { for (int i = 0; i < 10; ++i) { boost::mutex::scoped_lock lock(io_mutex); std::cout << id << ": " << i << std::endl; } }
int id; }; int main(int argc, char* argv[]) { boost::thread thrd1(count(1)); boost::thread thrd2(count(2)); thrd1.join(); thrd2.join(); return 0; }
Listing 3: Using the Boost.Bind library to simplify the code in Listing 2
// This program is identical to
// listing2.cpp except that it
// uses Boost.Bind to simplify
// the creation of a thread that
// takes data.
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>
boost::mutex io_mutex;
void count(int id)
{
for (int i = 0; i < 10; ++i)
{
boost::mutex::scoped_lock
lock(io_mutex);
std::cout << id << ": " <<
i << std::endl;
}
}
int main(int argc, char* argv[])
{
boost::thread thrd1(boost::bind(&count, 1));
boost::thread thrd2(boost::bind(&count, 2));
thrd1.join();
thrd2.join();
return 0;
}
#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <iostream>
boost::mutex io_mutex;
void count(int id) { for (int i = 0; i < 10; ++i) { boost::mutex::scoped_lock lock(io_mutex); std::cout << id << ": " << i << std::endl; } } int main(int argc, char* argv[]) { boost::thread thrd1(boost::bind(&count, 1)); boost::thread thrd2(boost::bind(&count, 2)); thrd1.join(); thrd2.join(); return 0; }
Condition Variables
#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/condition.hpp> #include <iostream>const int BUF_SIZE = 10; const int ITERS = 100;
boost::mutex io_mutex;
class buffer { public: typedef boost::mutex::scoped_lock scoped_lock; buffer() : p(0), c(0), full(0) { } void put(int m) { scoped_lock lock(mutex); if (full == BUF_SIZE) { { boost::mutex::scoped_lock lock(io_mutex); std::cout << "Buffer is full. Waiting..." << std::endl; } while (full == BUF_SIZE) cond.wait(lock); } buf[p] = m; p = (p+1) % BUF_SIZE; ++full; cond.notify_one(); }
int get() { scoped_lock lk(mutex); if (full == 0) { { boost::mutex::scoped_lock lock(io_mutex); std::cout << "Buffer is empty. Waiting..." << std::endl; } while (full == 0) cond.wait(lk); } int i = buf[c]; c = (c+1) % BUF_SIZE; --full; cond.notify_one(); return i; } private: boost::mutex mutex; boost::condition cond; unsigned int p, c, full; int buf[BUF_SIZE]; };
buffer buf;
void writer() { for (int n = 0; n < ITERS; ++n) { { boost::mutex::scoped_lock lock(io_mutex); std::cout << "sending: " << n << std::endl; } buf.put(n); } } void reader() { for (int x = 0; x < ITERS; ++x) { int n = buf.get(); { boost::mutex::scoped_lock lock(io_mutex); std::cout << "received: " << n << std::endl; } } } int main(int argc, char* argv[]) { boost::thread thrd1(&reader); boost::thread thrd2(&writer); thrd1.join(); thrd2.join(); return 0;
Thread Local Storage
#include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/tss.hpp> #include <iostream>boost::mutex io_mutex; boost::thread_specific_ptr<int> ptr;
struct count { count(int id) : id(id) { }
void operator()() { if (ptr.get() == 0) ptr.reset(new int(0));
for (int i = 0; i < 10; ++i) { (*ptr)++; boost::mutex::scoped_lock lock(io_mutex); std::cout << id << ": " << *ptr << std::endl; } }
int id; }; int main(int argc, char* argv[]) { boost::thread thrd1(count(1)); boost::thread thrd2(count(2)); thrd1.join(); thrd2.join(); return 0; }
Once Routines
Listing 6: A very simple use of boost::call_once
#include <boost/thread/thread.hpp> #include <boost/thread/once.hpp> #include <iostream>int i = 0; boost::once_flag flag = BOOST_ONCE_INIT;
void init() { ++i; }
void thread() { boost::call_once(&init, flag); } int main(int argc, char* argv[]) { boost::thread thrd1(&thread); boost::thread thrd2(&thread); thrd1.join(); thrd2.join(); std::cout << i << std::endl; return 0; }
The Future of Boost.Threads
Notes
[1] The POSIX standard defines multithreaded support in what’s commonly known as the pthread library. This provides multithreaded support for a wide range of operating systems, including Win32 through the pthreads-win32 port. However, this is a C library that fails to address some C++ concepts and is not available on all platforms.
[2] Visit the Boost website at <http://www.boost.org>.
[3] See Bjorn Karlsson’s article, “Smart Pointers in Boost,” in C/C++ Users Journal, April 2002.
[4] Douglas Schmidt, Michael Stal, Hans Rohnert, and Frank Buschmann. Pattern-Oriented Software Architecture Volume 2 —Patterns for Concurrent and Networked Objects (Wiley, 2000).
'프로그래밍 > C++' 카테고리의 다른 글
iexpress를 이용한 어플리케이션 재배포 패키지 만들기 (0) | 2012.12.15 |
---|---|
Determining which DLLs to Redistribute (어떤 DLL을 재배포할껀가?) (0) | 2012.12.15 |
STL (Standard Template Library) (0) | 2009.07.28 |
[30장 다형성] 순수 가상 함수 (0) | 2008.01.15 |
[27장] 정적 멤버 변수, 함수 (0) | 2008.01.10 |