- C++11
- 처음으로 threads, mutexes(locks), conditional variables 사용
- C++17
C++ Thread Library
<thread> header file 사용
std::thread를 통해 사용 가능
- thread(func(실행할 함수), args...)
- func이 return을 만날 때, thread는 종료됨
- thread를 생성하는 4가지 방법
- function pointer 사용
- functor (function object) 사용
- class member function 사용
- lambda expression 사용
- join()
- detach()
- 독립적으로 thread가 수행함
- detach() 이후, join이 허용되지 않음
- thread가 detach()없이 없애면 error가 생김
- mutex
<mutex> header file 사용
std::lock_guard는 mutex가 생성할 때 lock을 걸고 destruction할 때 unlock을 함.
#include <mutex>
std::mutex m;
m.lock();
m.unlock();
- atomic
- 연산을 atomic하게 함
- mutex lock보다 빠름
std::atomic<int> ai(o)
ai = 10;
std::cout << ai;
++ai;
--ai;
code
thread 생성
#include <iostream>
#include <thread>
#include <stdio.h>
long OddSum=0;
long EvenSum=0;
void findEven(long start, long end)
{
for (long i=start;i<=end;i++) if ((i&1)==0) EvenSum += i;
}
void findOdd(long start, long end)
{
for (long i=start;i<=end;i++) if ((i&1)==1) OddSum += i;
}
class FindOddFunctor {
public:
void operator()(int start, int end) {
for (int i=start;i<=end;i++) if ((i&1)==1) OddSum += i;
}
};
class FindOddClass {
public:
void myrun(int start, int end) {
for (int i=start;i<=end;i++) if ((i&1)==1) OddSum += i;
}
};
int main()
{
long start = 0, end = 1000;
std::thread t1(findEven, start, end);
std::thread t2([&](long s, long e) {
for (long i=s;i<=e;i++) if ((i&1)==1) OddSum += i;
}, start, end);
t1.join();
t2.join();
std::cout << "OddSum: " << OddSum << std::endl;
std::cout << "EvenSum: " << EvenSum << std::endl;
return 0;
}
count no lock
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
int inc_num=10001234;
int dec_num=10000000;
class CountLock {
int count;
public:
CountLock() : count(0) {}
int getCount()
{
return count;
}
void inc()
{
count++;
}
void dec()
{
count--;
}
};
class Producer
{
CountLock& c_lock;
public:
Producer(CountLock& clock): c_lock(clock) {
}
void run() {
for (int i=0;i<inc_num;i++) c_lock.inc();
}
};
class Consumer
{
CountLock& c_lock;
public:
Consumer(CountLock& clock): c_lock(clock) {
}
void run() {
for (int i=0;i<dec_num;i++) c_lock.dec();
}
};
int main()
{
CountLock count_lock;
Producer p(count_lock);
Consumer c(count_lock);
std::thread threadP(&Producer::run,&p);
std::thread threadC(&Consumer::run,&c);
threadP.join();
threadC.join();
std::cout<<"after main join count:"<<count_lock.getCount()<<std::endl;
return 0;
}
counter lock
#include <iostream>
#include <thread>
#include <mutex>
int inc_num=10001234;
int dec_num=10000000;
std::mutex m;
class CountLock {
int count;
public:
CountLock() : count(0) {}
int getCount()
{
int val;
m.lock();
val = count;
m.unlock();
return val;
}
void inc()
{
m.lock();
count++;
m.unlock();
}
void dec()
{
m.lock();
count--;
m.unlock();
}
};
class Producer
{
CountLock& c_lock;
public:
Producer(CountLock& clock): c_lock(clock) {
}
void run() {
for (int i=0;i<inc_num;i++) c_lock.inc();
}
};
class Consumer
{
CountLock& c_lock;
public:
Consumer(CountLock& clock): c_lock(clock) {
}
void run() {
for (int i=0;i<dec_num;i++) c_lock.dec();
}
};
int main()
{
CountLock count_lock;
Producer p(count_lock);
Consumer c(count_lock);
std::thread threadP(&Producer::run,&p);
std::thread threadC(&Consumer::run,&c);
threadP.join();
threadC.join();
std::cout<<"after main join count:"<<count_lock.getCount()<<std::endl;
return 0;
}
atomic
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
int inc_num=10001234;
int dec_num=10000000;
class CountLock {
std::atomic<int> count;
public:
CountLock() : count(0) {}
int getCount()
{
return count;
}
void inc()
{
count++;
}
void dec()
{
count--;
}
};
class Producer
{
CountLock& c_lock;
public:
Producer(CountLock& clock): c_lock(clock) {
}
void run() {
for (int i=0;i<inc_num;i++) c_lock.inc();
}
};
class Consumer
{
CountLock& c_lock;
public:
Consumer(CountLock& clock): c_lock(clock) {
}
void run() {
for (int i=0;i<dec_num;i++) c_lock.dec();
}
};
int main()
{
CountLock count_lock;
Producer p(count_lock);
Consumer c(count_lock);
std::thread threadP(&Producer::run,&p);
std::thread threadC(&Consumer::run,&c);
threadP.join();
threadC.join();
std::cout<<"after main join count:"<<count_lock.getCount()<<std::endl;
return 0;
}