개발/C·C++
-
condition_variable::wait개발/C·C++ 2021. 7. 26. 01:19
condition_variable는 생산자-소비자 모델에 쓰이는 클래스입니다. 멤버 함수인 wait 함수는 첫 번째 인자로 unique_lock을 받습니다. condition_variable 클래스는 오직 std::unique_lock을 통해서만 작동합니다. 이러한 제한은 일부 플랫폼에서 최대 효율을 만들 수 있습니다. 두 번째 인자는 predicate을 넣어주는데, 특정 조건을 만족하기 전까지 해당 스레드는 블록되며 원자적으로 언락됩니다. 블록된 스레드는 notifiy_all()이나 notify_one()이 실행될 때 블록이 풀리는데, 때로는 그냥 풀릴 수도 있습니다(spuriously). 블록이 풀리면, 락이 다시 획득되고 대기가 끝납니다. 예제 코드 #include #include #include ..
-
Default arguments개발/C·C++ 2021. 7. 5. 14:39
사소한 거지만 데 잠시 고민해봤습니다. 왜 디폴트 매개변수는 오른쪽 끝에서부터만 가능한 걸로 제한을 걸었을까. 함수를 호출할 때 왼쪽부터 인수를 채웁니다. 선언된 순서대로 매개변수를 넣어줘야 합니다. 사실 그렇게 하지 않으면 바로 컴파일 에러가 발생해버립니다. 그렇기 때문에 디폴트 매개변수 기능을 만들 때 반대 방향인 오른쪽에서부터 하도록 강제하면 개발자가 실수로라도 함수를 잘못 설계하는 일이 매우 적어지는 것 같습니다. 또한 기본 함수 호출 규약인 __cdcel이 파라미터를 오른쪽부터 전달하기 때문에 파라미터에 디폴트로 값을 넣어야 한다면 오른쪽부터 하는 것이 더 안전해보입니다.
-
[Template] 템플릿 구체화개발/C·C++ 2021. 7. 5. 04:19
STL 컨테이너를 보면 선언과 정의가 분리되어 있지 않습니다. 클래스는 선언부와 정의부를 나누는 경우가 조금 더 일반적일 텐데요. 일반화 프로그래밍이라는 템플릿 라이브리리는 일반적인 방법을 따르지 않는 것처럼 보입니다. 라이브러리를 만드는 사람들이 뭘 몰라서 그런 것은 아닐 테니까, 그럴 만한 이유가 있을 겁니다. 그 이유를 파악해 봅시다. #include int main() { std::vector vec; for (int i = 0; i < 5; ++i) vec.push_back(i); } 간단한 벡터 예제입니다. 연산자를 통해 int형 데이터를 담을 수 있는 컨테이너를 만들어 반복문을 이용해 0부터 4까지 넣었습니다. std::vector을 명시적 구체화라고 합니다. 함수 템플릿에 넣는 인수를 통해..
-
[Priority queue] 간단한 참고개발/C·C++ 2021. 7. 3. 21:34
cppreference를 보면 내부적으로 디폴트로 vector을 이용해 데이터를 저장하며 정렬 방식은 오름차순인 것을 알 수 있습니다. less가 왜 오름차순인 이유는 왼쪽 항을 기준으로 a < b이기 때문에 결과적으로 오름차순이 됩니다. 우선순위 큐는 데이터의 최대값, 최소값을 찾고 싶을 때 유용합니다. 상수 시간으로 찾을 수 있습니다. 그렇다면 다음의 결과가 어떻게 될까요? priority_queue pq; pq.emplace(3); pq.emplace(5); pq.emplace(2); pq.emplace(4); pq.emplace(1); while (!pq.empty()) { cout
-
Guaranteed Copy Elison개발/C·C++ 2021. 6. 27. 18:15
>> 번역글입니다 >> 의역은 있고 오역이 있을 수 있습니다 >> 출처 https://jonasdevlieghere.com/guaranteed-copy-elision/ Copy Elision C++17 표준의 변화를 논의하기 전에, C++14 표준에 정의되어 있던 복사 생략의 기본을 다시 살펴보는 것이 도움이 될 수 있습니다. 복사 생략이 무엇이고 어떻게 동작하는지 안다면 이 파트는 건너뛰어도 됩니다. Foo 구조체는 모든 예제에서 사용됩니다. 생성자와 소멸자가 호출될 때마다 해당 정보들이 출력될 것입니다. struct Foo { Foo() { std::cout
-
InterlockedExchange, InterlockedCompareExchange개발/C·C++ 2021. 6. 10. 18:34
Target이 역참조하는 값을 Value로 만들고 원래의 값을 반환합니다. 가능하면 컴파일러 내장함수를 이용해 구현됩니다 .이 함수는 멀티스레드가 공유하는 변수에 동기적으로 접근할 수 있는 방법을 제공합니다. 원자적으로 작동합니다. _InterlockedExchange 함수는 Win32 Window SDK InterlockedExchange 함수에 컴파일러 내장 지원을 제공합니다. 원자적으로 비교/변경 동작을 수행합니다. 포인터를 변경하고 싶다면 InterlockedCompareExchangePointer 함수를 사용합니다. 이 함수는 Destination과 Comarand를 비교합니다. Destination이 Comparand와 같다면 Exchange가 Destination에 저장됩니다. 반환 값은 D..
-
timeBeginPeriod function개발/C·C++ 2021. 6. 10. 17:36
Sleep 함수를 이용하면 인수로 넣은 수의 밀리세컨드만큼 스레드가 잠들어있다가 깨어납니다. 스레드가 Sleep 함수를 호출하면 운영체제는, 타이머 인터럽트가 실행될 때 스레드가 실행할 수 있도록 예약을 걸어 놓습니다. 시스템은 Sleep 함수의 인수로 받은 시간을 보장하지 않습니다. 타이머 인터럽트 간격은, 최근 컴퓨터는 일반적으로 15.625ms입니다(1000ms 64로 나눈 값). 이보다 빠를 수도, 조금 느릴 수도 있습니다. 더 작은 간격으로 타이머를 사용하고 싶다면 timeBeginPeriod 함수를 사용할 수 있습니다. 인수는 밀리세컨드 단위입니다. 1을 넣어도 문제는 없겠지만 더 정확하게 사용하기 위해서는 TIMECAPS 객체와 timeGetDevCaps 함수를 이용하는 것이 좋습니다. 타이..
-
WSASend function개발/C·C++ 2021. 6. 6. 22:38
마이크로소포트의 윈도우 개발자 문서에서 WSASend 함수 설명을 읽다 보면 재미있는 문장 하나를 발견하게 됩니다. 너무 당당해서 그런가 보다 넘어갈 수도 있는데, 이 부분에 대한 처리를 꼭 해줘야 합니다. WSASend 함수를 호출하기 위해 인수를 세팅해줄 때 전송할 데이터의 크기를 따로 저장합니다. 스레드가 완료 큐에서 가져온 메시지를 처리할 때 실제 전송된 바이트의 수와 데이터의 크기를 비교해서, 전송됐어야 할 데이터의 크기보다 전송된 실제 바이트가 작다면 WSASend() 함수를 다시 호출해야 합니다. WSASend 함수를 호출하기 전에 인수를 세팅할 때, WSABUF의 buf를 실제 전송한 사이즈 만큼 포인터를 앞으로 옮겨줘야 하며 WSABUF의 len은 사이즈만큼 빼야 합니다.