26. 동시 처리 한도 제한기의 허가 반납 누락 (permit leak → throttle 고갈)
난이도 중 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// ============================================================================
// [코드리뷰 문제] C# - 동시 처리 한도 제한기(세마포어)의 허가 반납 누락
// ----------------------------------------------------------------------------
// 시나리오 (서버 내부 · 동시성/자원 제한):
// - 결제 검증·외부 API 호출처럼 비싼 작업의 동시 실행 수를 N 개로 제한하려고
// SemaphoreSlim 으로 throttle 을 만들었다.
// - 작업은 실패(예외)할 수 있고, 사전 점검에서 거절(조기 반환)될 수도 있다.
// - RunAsync 는 여러 요청 스레드/태스크에서 끊임없이 호출된다.
//
// 과제:
// 이 코드의 잠재적 문제를 모두 찾고, 작업이 자주 예외를 던지거나 사전 점검에서 자주
// 거절될 때 시간이 지나면서 throttle 이 어떤 상태가 되는지 설명하라. 수정안과 더 나은
// 설계를 제시하라. (먼저 직접 리뷰를 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
using System;
using System.Threading;
using System.Threading.Tasks;
public enum Outcome { Ok, Rejected }
public class RequestThrottle
{
private readonly SemaphoreSlim _sem;
public RequestThrottle(int maxConcurrent)
{
_sem = new SemaphoreSlim(maxConcurrent, maxConcurrent);
}
private bool IsHealthy() => /* 외부 시스템 상태 점검 */ true;
public async Task<Outcome> RunAsync(Func<Task> op)
{
await _sem.WaitAsync(); // (A) 허가 획득
if (!IsHealthy()) // (B) 사전 점검 — 실패면 거절
return Outcome.Rejected;
await op(); // (C) 비싼 작업 (예외를 던질 수 있음)
_sem.Release(); // (D) 허가 반납
return Outcome.Ok;
}
} 결함 코드 · C++
// ============================================================================
// [코드리뷰 문제] C++ - 동시 처리 한도 제한기(세마포어)의 허가 반납 누락
// ----------------------------------------------------------------------------
// 시나리오 (서버 내부 · 동시성/자원 제한):
// - 외부 API 호출 등 비싼 작업의 동시 실행 수를 N 개로 제한하려고
// 카운팅 세마포어(mutex + condition_variable 로 구현)로 throttle 을 만들었다.
// - 작업(op)은 예외를 던질 수 있고, 사전 점검에서 조기 반환될 수도 있다.
// - run 은 여러 워커 스레드에서 끊임없이 호출된다.
//
// 과제:
// 이 코드의 잠재적 문제를 모두 찾고, op 가 자주 예외를 던지거나 사전 점검에서 자주
// 거절될 때 시간이 지나면서 throttle 이 어떤 상태가 되는지 설명하라. 수정안과 더 나은
// 설계를 제시하라. (먼저 직접 리뷰를 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
#include <mutex>
#include <condition_variable>
#include <functional>
enum class Outcome { Ok, Rejected };
// 카운팅 세마포어 (count 개의 허가)
class Semaphore {
public:
explicit Semaphore(int count) : count_(count) {}
void acquire() {
std::unique_lock<std::mutex> lk(m_);
cv_.wait(lk, [&]{ return count_ > 0; });
--count_;
}
void release() {
std::lock_guard<std::mutex> lk(m_);
++count_;
cv_.notify_one();
}
private:
std::mutex m_;
std::condition_variable cv_;
int count_;
};
class RequestThrottle {
public:
explicit RequestThrottle(int maxConcurrent) : sem_(maxConcurrent) {}
Outcome run(const std::function<void()>& op) {
sem_.acquire(); // (A) 허가 획득
if (!isHealthy()) // (B) 사전 점검 — 실패면 거절
return Outcome::Rejected;
op(); // (C) 비싼 작업 (예외를 던질 수 있음)
sem_.release(); // (D) 허가 반납
return Outcome::Ok;
}
private:
bool isHealthy() const { return true; } // 외부 상태 점검(생략)
Semaphore sem_;
}; 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.
내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.