5

원격 시스템에서 메시지를 수신하고 메시지를 디스크의 파일에 작성해야하는 프로그램을 작성 중입니다. 이 프로그램의 목적은 메시지를받는 라이브러리의 성능을 테스트하는 것이므로 디스크에 메시지를 쓰는 것이 라이브러리의 성능에 영향을주지 않도록해야한다는 사실에 내가 찾는 어려움이 있습니다. . 라이브러리는 콜백 기능을 통해 프로그램에 메시지를 전달합니다. 또 다른 어려움은 솔루션이 플랫폼에 독립적이어야한다는 것입니다.파일에 플랫폼 독립적 인 비동기 쓰기를 구현하는 방법은 무엇입니까?

어떤 옵션이 있습니까?

나는 생각 다음 boost:asio를 사용

  • 이 파일에 쓸 수 있지만,이 파일에 대한 비동기 쓰기는이 라이브러리의 윈도우 특정 부분에 있는지 (this 설명서를 참조하십시오) 것 같다 - 그래서이 될 수 없다 익숙한.
  • boost::interprocess을 사용하여 메시지 대기열을 만들었지 만 this documentation은 메시지를 보낼 수있는 3 가지 방법이 있음을 나타내며 메시지 대기열이 꽉 찼을 때 모든 방법으로 프로그램이 (암시 적으로 또는하지 않음) 차단해야합니다. 위험.
  • std::deque<MESSAGES>을 생성하여 콜백 함수에서 deque로 푸시하고 파일에 쓰는 동안 (별도 스레드에서) 메시지를 팝하지만 STL 컨테이너는 not guaranteed to be thread-safe입니다. deque를 밀고 잠글 수는 있지만 연속 메시지 간에는 약 47 마이크로 초가 걸리므로 잠글 수는 없습니다.

가능한 해결책에 대해 더 많은 아이디어가 있습니까?

+0

메시지 사이에 47 마이크로? 그것은 원격 기계 종지입니까? –

답변

2

STL 컨테이너는 스레드로부터 안전하지 않을 수 있지만 다른 스레드에서 다른 시간에 사용할 수없는 STL 컨테이너를 공격하지 않았습니다. 소유권을 다른 스레드에 전달하는 것이 안전합니다. 나는 몇 번 다음 사용하고, 그래서 그것을 작동 알고

:

  • 는 표준 : : 벡터에 대한 포인터를 만듭니다.
  • 벡터 포인터를 보호하기 위해 뮤텍스 잠금을 만듭니다.
  • 새로운 []을 사용하여 std :: vector를 만든 다음 큰 크기를 예약하십시오(). 수신기 스레드에서

는 : 큐에 항목을 추가 할 때마다

  • 는 뮤텍스를 잠급니다. 짧은 자물쇠가 있어야합니다.
  • 대기열 항목을 추가하십시오.
  • 잠금 장치를 해제하십시오.
  • 조건 변수를 알리는 것 같은 느낌이 들면. 때로는 그렇지 않습니다. 디자인에 달려 있습니다. 볼륨이 매우 높고 수신 측에서 일시 중지가없는 경우 조건을 건너 뛰고 대신 폴링하십시오.

    • 이동 폴링 또는 조건 변수에서 대기로 할 일이 찾을 :
    • 잠금 큐 뮤텍스 소비자 스레드 (디스크 작가)에

    .

  • 대기열 길이를보십시오.
  • 큐에 작업이있는 경우 소비자 스레드의 변수에 포인터를 할당하십시오.
  • new [] 및 reserve()를 사용하여 새 대기열 벡터를 만들고이를 대기열 포인터에 할당합니다.
  • 뮤텍스의 잠금을 해제하십시오.
  • 이동하여 항목을 디스크에 씁니다.
  • 삭제 [] 사용 대기열 벡터.

이제 문제에 따라 차단할 수있는 방법이 필요합니다. 예를 들어 나의 프로그램 중 하나에서 큐 길이가 100,000 개를 초과하면 생성 스레드는 1 초의 절전 모드를 시작하고 많은 불평을 시작합니다. 그것은 일어나지 않아야하는 것들 중 하나입니다. 그렇기 때문에 그것을 고려해야합니다. 제한이 없으면 컴퓨터의 모든 메모리를 사용하고 예외가 발생하여 충돌이 발생하거나 OOM에 의해 사망하거나 스왑 폭풍으로 막을 수 있습니다.

+0

방금 ​​다른 답변을 읽었습니다. 항목 당 잠금이 너무 비싸면이 요구 사항에 맞게 조정할 수 있습니다. 그냥 벡터 포인터의 벡터를 유지하고 그것을 작성 완료되면 벡터를 추가하십시오. –

+0

또 다른 메모 : mutex가 경합이 없을 때 매우 저렴한 비용으로 futex를 사용하는 리눅스에서이 디자인은 나를 위해 정말 잘 돌아갔다. 그리고 CriticalSection을 사용하는 BSD 나 Windows에서는 나쁘지 않습니다. 그러나 당신이 매우 다중 플랫폼이되고 싶기 때문에 중첩 된 컨테이너 잠금이 실제로 최고 일 수 있습니다. –

2

boost :: thread는 플랫폼 독립적이므로 블로킹 쓰기를 수행하는 스레드를 만드는 데 활용할 수 있어야합니다.

std::deque<std::deque<MESSAGES> > 

그런 경우에만 최상위 수준의 양단을 고정 : 당신과 같은 중첩 된 컨테이너를 작성하여 이중 버퍼링 기술에 수정을 활용할 수있는 용기에게 메시지가 메인 스레드에 배치 될 때마다 고정 할 필요 방지하려면 메시지가 가득 찬 deque가 추가 될 준비가되었습니다. 쓰레드는 차례로 최상위 레벨 양단 큐를 잠그고 작성 될 메시지들로 가득 찬 양단 큐 (deque)를 튀어 나오게 할 것이다.