C++ Thread
#include <thread> // 선언.
using namesapce std;
void somefunction()
{
for (int cnt =0; cnt < 1000; ++cnt)
cout << "thread function" << cnt << endl;
}
int main()
{
thread Thread(&somefunction, <argv>) //인자는 최대 4개까지 넘길 수 있다 한다.
Thread.join();
/*
스레드 메인함수가 리턴해줄때까지 기다렸다가 종료해준다. 안쓰면 에러난다.
ex) 만약 스레드 메인함수에서 리턴이 없이 while(true)라면 해당 스레드는 block 상태이기때문에 무한정 기다릴것이다.
join()을 쓰면 생각보다 느리다.
Thread.detach(); 를 쓰면 join을 안써도된다.
detach 함수는 thread 오브젝트에 연결된 스레드를 떼어낸다고 한다.
thread 객체를 지우고싶을땐 detach를 한 후 지우는 방법이 있다한다.
그외엔 joinable(); 이라는 함수를 통해 확인 후 지우는 방법도 있다한다.
*/
return 0;
}
lambda 형식으로 thread 사용가능.
lambda 형식? [captures](parameters) -> return type { body } // <참고> // [captures]에서 &(참조)로 받으면 lambda내에서 변수 값을 변경할 수 있다. // 하지만, 복사로 받는다면 lambda내에서 값을 변경할 수 없다. ex) thread Thread([]() { body... } )
mutex
#include <iostream>
using namespace std;
int main()
{
thread Thread1([] (){
for (int cnt =0; cnt < 1000; ++cnt)
cout << "thread function" << cnt << endl;
});
thread Thread2([](){
for (int cnt =0; cnt < 1000; ++cnt)
cout << "thread function" << cnt << endl;
});
...
return 0;
}
위와 같을때, 여러 쓰레드에서 cout(공유자원)을 모두 참조하게된다.
이 현상을 data-race라 한다.
해결하기위해서 mutex를 쓸 수 있다.
#incude <mutex>
using namespace std;
mutex mtx_lock;
thread Thread1([] (){
for (int cnt =0; cnt < 1000; ++cnt)
mtx_lock.lock();
cout << "thread function" << cnt << endl;
mtx_lock.unlock();
});
위처럼 공유자원에대해 lock, unlock 함으로써 다른 쓰레드에서 접근하지 못하게 해준다.
(try_lock도 있다. 참고하자)
하지만 lock, unlock을 자주 남발하면 속도가 굉장히 느려질것이다.
간단한 증가,증감 연산경우에는 atomic을 사용할 수 있다.
atomic
#include <iostream>
#include <atomic>
using namespace std;
int main()
{
atomic<int> at =1; //<type>
at.fetch_add(1);
return 0;
}
atomic 으로 변수를 선언해준다.
atomic으로 선언된 변수는 초기에만 값을 대입할 수 있다. 이후에는 대입이 불가능하다.
또, atomic 변수가 동작하고 있는동안에는 다른 스레드에서 접근이 불가능하다.
(mutex.lock, unlock()을 fetch_add() 한줄로 대신한다고 보자.)
반응형
'Language > C++' 카테고리의 다른 글
c++ malloc new 차이점? (0) | 2019.01.26 |
---|---|
c++ vector capacity (0) | 2019.01.08 |
c++ Operator (0) | 2018.12.29 |