하나의 cpu 코어로 여러개의 프로세스를 동시에 가동하는 것 처럼 보이는 것은
운영체제의 스케쥴러에 따라서 
컨텍스트 스위칭 되가면서 번갈아 실행되고 잇는 것

쓰레드란?
cpu코어에서 돌아가는 프로그램 단위를 쓰레드라고 부름
프로세스가 아니엇나봐?
cpu 코어 한개는 한번에 하나의 쓰레드를 실행시킴

한개의 프로세스는 최소 한개의 쓰레드로 이루어져 잇음
여러개의 쓰레드로 구성된 프로그램을 멀티쓰레드 프로그램이라고 함

쓰레드와 프로세스의 차이
프로세스들은 메모리를 공유하지 않음
프로세스1은 프로세스2의 메모리에 접근 불가능하고 프로세스2는 프로세스1의 메모리에 접근 불가능 
하지만 한 프로세스 안에 잇는 여러 쓰레드는 같은 메모리를 공유함
쓰레드1과 쓰레드2가 같은 변수에 접근할 수 있음

현대 기술의 발전으로 cpu는 코어가 한개가 아니고 여러개임
그러므로 멀티코어 cpu에서는 각 코어에서 각기 다른 쓰레드들이 동시에 실행되고 잇음

코어가 늘어나면서 멀티쓰레드로 프로그램을 만드는게 유리해짐

멀티쓰레드로 만들기 유리한 프로그램은?
- 병렬 가능한 작업들
  1~10000까지 더하는 작업을 단일 쓰레드 프로그램으로 짠다면 그냥 for문으로 1~10000까지 더하면 됨
  하지만 이걸 10개의 쓰레드로 만든다면
  1번쓰레드는 1~1000까지, 2번 쓰레드는 1001~2000까지... 하고나서 다 합치면
  실행시간이 거의 10분의 1 수준이 될 수 잇음

하지만 모든 프로그램을 멀티쓰레드로 짠다고 유리한게 아님
피보나치 수열의 경우 n번째를 구하기 위해선 n-1과 n-2를 알아야함. 그리고 n+1을 구하기 위해선 n과 n-1을 알아야하고
그러니 다음 연산을 하려면 이전 연산의 결과가 필요한 이런 경우 병렬화가 매우 어려움

- 대기시간이 긴 작업들
인터넷에 잇는 자료를 스크랩 한다면 인터넷 속도가 cpu속도보다 느리므로 응답을 기다리기만 하는 시간이 생김
이런 경우 여러개의 쓰레드로 요청하고 응답이 오기까지 또 다른 쓰레드가 요청하고 또 다른 쓰레드가 요청하고
이러다가 응답이 오면 다운받고, 또 다운받고 하면 대기시간에도 다른 일을 할 수 있음

쓰레드 생성법
C++ 11 이전에는 표준이 없어서 리눅스는 pthread_create로, 윈도우는 CreateThread로 만드는 등 복잡햇지만
C++ 11 이후로는 표준이 나와서 쉽게 사용 가능
#include <thread> // 헤더파일
thread t1(func1); // 객체 생성
// t1객체는 인자로 받은 func1을 새로운 쓰레드에서 실행함
thread t2(func2); // 이런식으로 여러 쓰레드를 만들어서 동시 실행 가능
// 단 스케쥴러 마음대로 조정되는거라 완전 동시는 아님
t1.join(); // join은 해당 쓰레드가 종료되면 리턴하는 함수
// 즉 t1.join()은 t1이 종료될때까지 리턴하지 않음
// 쓰는 이유는 쓰레드가 종료되기도 전에 메인함수가 종료되서 쓰레드 객체들이 소멸하는것을 막기 위해
// join은 쓰레드가 종료되어야만 리턴하므로, t1.join()해두면 쓰레드가 종료될때까지 리턴되지 않고, 즉 코드 다음줄들은 실행되지 않고 대기중인 셈이 되는 것
t1.detach(); // detach는 쓰레드 실행시킨 후 잊어버린다라는 개념. 메인함수가 종료되어도 백그라운드에서 쓰레드는 계속 작동함
// join은 결과를 꼭 확인해야할 때, detach는 결과를 눈으로 보는게 아니라 실행시키는것이 중요할 때 쓰는 듯

// detach는 메인함수와 상관없이 t1의 일이 끝나면 쓰레드가 소멸함

쓰레드가 cout을 하게 되면 쓰레드 이것저것이 계속 스위칭되면서 출력해서 문장이 제대로 출력이 안됨

이유는 cout << a << b;를 하게 되면 cout << a까지 잘 하고나서 << b를 수행하기 전 그 틈에 interupt가 들어올 수 있어서
반면 printf는 문장 ~~~가 있으면 컨텍스트스위칭이 되더라도 ~~~가 출력 다 되게 만들기 때문에 쓰레드가
값을 출력할땐 printf를 써주면 좋을 듯