여러 발신자와 수신자가있는 Haskell에서 메시지 전달 동시성

78t66

여러 발신자와 수신자가 관련된 문제를 해결하려고 노력 중이며 내 접근 방식이 올바른 방향인지에 대한 피드백을 받고 싶습니다.

문제 : N 명의 리더와 M 명의 팔로워가 있는데 모두 개별 스레드로 대표되어야합니다. 모든 사람은 댄서이며 8 개의 다른 춤 이름이있는 "댄스 카드"를 가지고 있습니다. 각 리더는 추종자에게 특정 댄스를 추를 수 있는지 물어봐야합니다. 추종자들은 리더의 초대를 기다리고 이미 그 춤을 추지 않았고 다른 2 개의 춤을이 리더와 춤추는 데 동의하지 않은 경우에만 수락합니다. 리더가 초대가 수락되었다는 소식을 듣게되면 다음 댄스 경기를 확보하기 위해 계속 노력합니다. 그렇지 않으면 그들은 같은 춤에 대한 일치를 계속 찾으려고 노력합니다. 마지막으로 리더 "댄스 카드"에는 각 댄스와 함께 춤을 추는 추종자의 ID가 인쇄됩니다.

접근 방식 : 리더와 팔로워라는 두 가지 기능을 만들었습니다. 주로 forkIO를 사용하여 리더를 n 번, 팔로워를 m 번 호출합니다. 그러나 상태를 유지하는 방법 (특히 댄스 카드)에 대한 문제가 있습니다. 저는 "Dancer"유형 클래스를 만들고 두 가지 인스턴스 인 Leader와 Follower를 만들 생각 중이었습니다. 각 리더와 각 팔로워는 고유 ID (1에서 N 또는 M까지)를 갖습니다. 또한 각각의 개인 메일 함으로 사용할 mvar가 필요합니다. 리더는 동일한 팔로워가 그것을 꺼내고 초대에 예 또는 아니오로 응답 할 수 있도록 어떤 것을 넣기 위해 어떻게 든 팔로워의 mvar를 "가져올"필요가있을 것입니다. 댄스 카드에 관해서는 상태 모나드를 통합하는 것이 최선이라고 생각합니다. 예를 들어, 리더가 추종자를 댄스에 초대하면

KA Buhr

와, 이미 타입 클래스, 두 개의 인스턴스, 상태 모나드가 있고 MVar의 타입도 정해지지 않았습니다! 상황이 복잡해지고 있습니다.

나는 당신이 Haskell-as-Java 함정에 빠지게 될지도 모른다고 걱정합니다. 여기서 당신은 당신의 머릿속에서 객체 지향 솔루션을 생각 해냈고, 이제 당신은 그것을 Haskell로 직접 번역하려고 노력하고 있습니다. 공유 메서드가 "클래스"등으로 래핑 된 상태 저장 개체

나는 다른 접근법을 제안 할 것입니다. 댄서는 "사물"이 아닙니다. 그들은 작업입니다. 관용적 Haskell에서 일반적으로 사용되는 것처럼 간단한 함수로 구현하고 "상태"대신 인수 전달 및 재귀를 사용합니다.

스포일러가 뒤 따르지만 여기에를 갖고 있고 id요청 / 응답 MVar 쌍을 통해 요청에 응답하고 재귀 코어 루프를 사용하여 댄스 카드를 유지하는 "팔로어"를 정의하는 간단한 방법이 있습니다. 있습니다 Follower데이터 형식 (예를 들어, 그것은 더 댄스 카드가 없음)는 "추종자 객체"있어야되지 않으며, follower팔로어 작업을 식별하고 통신하기위한 "핸들"역할을하는 반환 값을 문서화하는 편리한 방법 일뿐입니다 .

type LeaderId = Int
type FollowerId = Int
type Dance = Int

-- |A dance card for a follower with a list of dance/leader pairs.
data Card = Card { getCard :: [(Dance, LeaderId)] } deriving (Show)
emptyCard = Card []

-- |Follower handle giving its id and request/response MVars
data Follower =
  Follower { followerId :: FollowerId
           , request :: MVar (Dance, LeaderId)
           , response :: MVar Bool
           }

-- |Create a new follower task with given id.
follower :: FollowerId -> IO Follower
follower followerId_ = do
  req <- newEmptyMVar
  res <- newEmptyMVar
  let loop (Card xs) = do
        -- get next request
        (dance, leaderId_) <- takeMVar req
        case lookup dance xs of
          -- if dance is free and we haven't danced too often w/ this leader
          Nothing | length (filter ((==leaderId_) . snd) xs) < 2
                    -- then say yes and update dance card
                    -> do putMVar res True
                          loop (Card $ (dance, leaderId_) : xs)
          -- otherwise, refuse
          _         -> do putMVar res False
                          loop (Card xs)
  forkIO $ loop emptyCard
  return $ Follower followerId_ req res

춤을 추도록 요청하여 두 명의 팔로워를 만들고 테스트 할 수 있습니다.

> f1 <- follower 1   -- follower #1
> f2 <- follower 2   -- follower #2
> putMVar (request f1) (1, 10) -- dance #1 w/ leader #10
> takeMVar (response f1)
True                           -- hooray!
> putMVar (request f1) (1, 14) -- dance #1 w/ leader #14
> takeMVar (response f1)
False                          -- wah! dance is taken
> putMVar (request f2) (1, 14) -- try different follower
> takeMVar (response f2)
True                           -- hooray!
>

이 특정 추종자들은 댄스 카드를 요청하거나 무한 루프를 종료하도록 지시 할 수 없습니다. 이 응용 프로그램에는 필요하지 않습니다 (우리는 리더의 댄스 카드 만 필요하며 답변을 얻을 때 많은 경량 스레드가 붙어 있더라도 상관하지 않습니다), 다음과 같은 경우 항상 몇 개의 MVar를 추가 할 수 있습니다. 당신은했다.

마찬가지로 간단한 재귀 코어 루프를 사용하여 리더를 함수로 구현할 수 있어야합니다. 리더가 순서대로 댄스 카드를 채우려 고하면 실제로 댄스 카드를 추적 할 필요가 없습니다. 최종 댄스 카드 (및 "코어 루프")는 mapM너무 많이 시도합니다. 댄스 슬롯 1 ~ 8을 채 웁니다.

추종자에게 춤을 요청할 수있는 능력을 리더에게 어떻게 제공합니까? 글쎄, 먼저 전체 팔로어 세트를 만들고 팔로어 핸들 목록 ( [Follower])을 leader생성 함수에 대한 인수로 전달 합니다. 지도자로부터 댄스 카드를 어떻게 되찾나요? leader기능은 카드에 대한 MVAR을 반환해야하고, main기능을 할 수있는 mapM takeMVar leadersDanceCards댄스 카드의 전체 목록을 얻을 수 있습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Python을 사용하여 동일한 시스템에서 신뢰할 수있는 발신자와 수신자 시뮬레이션

분류에서Dev

PostgreSQL에서 여러 수신자가있는 메시지를 저장하는 방법은 무엇입니까?

분류에서Dev

reactjs에서 발신자와 수신자 사이에 메시지를 올바르게 표시하는 방법

분류에서Dev

Azure ServiceBus는 자동 전달시 메시지에 특성을 연결합니다.

분류에서Dev

수천 개의 "메일 전송 실패 : 발신자에게 메시지를 돌려주는 중"수신

분류에서Dev

Pub / Sub 및 메시징 대기열의 여러 소비자에 대한 메시지 전달 보장

분류에서Dev

C # 서버를 사용하여 여러 사용자에게 Firebase 클라우드 메시지 전달

분류에서Dev

한 명의 수신자가 동시에 여러 발신자로부터 패킷을 받았을 때 openfire 서버는 어떻게 작동합니까?

분류에서Dev

마지막 발신자가 삭제되었지만 수신자가 여전히 활성 상태 일 때 Tokio MPSC에 항목을 보존 할 수 있습니까?

분류에서Dev

메시지를 회신하거나 전달할 때 잘못된 "보낸 사람"전자 메일을 사용하는 여러 계정 설정이있는 Outlook 2016

분류에서Dev

ajax 자동 완성 메소드에서 여러 값을 전달하는 방법

분류에서Dev

여러 개의 인수를 웹 메소드에 매개 변수로 전달하는 동안 "No webservice found at"메시지가 발생합니다.

분류에서Dev

Rails : 이메일에서 수신 거부 링크를 사용하여 발신자 이메일 및 수신자 이메일을 전달하는 방법

분류에서Dev

Rails : 이메일에서 수신 거부 링크를 사용하여 발신자 이메일 및 수신자 이메일을 전달하는 방법

분류에서Dev

Java NIO에서 동시에 여러 발신 연결 생성

분류에서Dev

Akka FSM에서 여러 수신 메시지 일치 가능

분류에서Dev

Facebook 메신저에서 전달 된 JSON 메시지 처리

분류에서Dev

여러 발신자와 단일 수신자가있는 UDP

분류에서Dev

여러 수신자에게 메시지를 보낼 때 배열로 신속 / 핵심 데이터 가져 오기

분류에서Dev

여러 수신자에게 메시지를 보낼 때 배열로 신속 / 핵심 데이터 가져 오기

분류에서Dev

BroadcastChannel 메시지 수신 후 발신자에게만 답장 할 수있는 방법이 있나요?

분류에서Dev

Microsoft Graph API에서 전자 메일 메시지에 대한 전달 및 회신 결정

분류에서Dev

나는 RabbitMQ를 사용하여 사용자 정의 알고리즘 대신 라운드 로빈으로 메시지를 전달할 수 있습니까?

분류에서Dev

nodejs에서 전달되는 자바 스크립트 메시지

분류에서Dev

DocuSign : 여러 서명자 수신자가 작동하지 않음

분류에서Dev

각도의 사용자 지정 지시문에 동적 메서드 전달

분류에서Dev

낙타 수신자 목록이 메시지를 전달하는 방법

분류에서Dev

JMS 메시지 ID는 JMS 서버가 메시지를 수신 한 순서를 나타 냅니까? 메시지 주문 전달

분류에서Dev

셀러리는 차단되지 않는 발신자에게 상태 업데이트를 전달할 수 있습니까?

Related 관련 기사

  1. 1

    Python을 사용하여 동일한 시스템에서 신뢰할 수있는 발신자와 수신자 시뮬레이션

  2. 2

    PostgreSQL에서 여러 수신자가있는 메시지를 저장하는 방법은 무엇입니까?

  3. 3

    reactjs에서 발신자와 수신자 사이에 메시지를 올바르게 표시하는 방법

  4. 4

    Azure ServiceBus는 자동 전달시 메시지에 특성을 연결합니다.

  5. 5

    수천 개의 "메일 전송 실패 : 발신자에게 메시지를 돌려주는 중"수신

  6. 6

    Pub / Sub 및 메시징 대기열의 여러 소비자에 대한 메시지 전달 보장

  7. 7

    C # 서버를 사용하여 여러 사용자에게 Firebase 클라우드 메시지 전달

  8. 8

    한 명의 수신자가 동시에 여러 발신자로부터 패킷을 받았을 때 openfire 서버는 어떻게 작동합니까?

  9. 9

    마지막 발신자가 삭제되었지만 수신자가 여전히 활성 상태 일 때 Tokio MPSC에 항목을 보존 할 수 있습니까?

  10. 10

    메시지를 회신하거나 전달할 때 잘못된 "보낸 사람"전자 메일을 사용하는 여러 계정 설정이있는 Outlook 2016

  11. 11

    ajax 자동 완성 메소드에서 여러 값을 전달하는 방법

  12. 12

    여러 개의 인수를 웹 메소드에 매개 변수로 전달하는 동안 "No webservice found at"메시지가 발생합니다.

  13. 13

    Rails : 이메일에서 수신 거부 링크를 사용하여 발신자 이메일 및 수신자 이메일을 전달하는 방법

  14. 14

    Rails : 이메일에서 수신 거부 링크를 사용하여 발신자 이메일 및 수신자 이메일을 전달하는 방법

  15. 15

    Java NIO에서 동시에 여러 발신 연결 생성

  16. 16

    Akka FSM에서 여러 수신 메시지 일치 가능

  17. 17

    Facebook 메신저에서 전달 된 JSON 메시지 처리

  18. 18

    여러 발신자와 단일 수신자가있는 UDP

  19. 19

    여러 수신자에게 메시지를 보낼 때 배열로 신속 / 핵심 데이터 가져 오기

  20. 20

    여러 수신자에게 메시지를 보낼 때 배열로 신속 / 핵심 데이터 가져 오기

  21. 21

    BroadcastChannel 메시지 수신 후 발신자에게만 답장 할 수있는 방법이 있나요?

  22. 22

    Microsoft Graph API에서 전자 메일 메시지에 대한 전달 및 회신 결정

  23. 23

    나는 RabbitMQ를 사용하여 사용자 정의 알고리즘 대신 라운드 로빈으로 메시지를 전달할 수 있습니까?

  24. 24

    nodejs에서 전달되는 자바 스크립트 메시지

  25. 25

    DocuSign : 여러 서명자 수신자가 작동하지 않음

  26. 26

    각도의 사용자 지정 지시문에 동적 메서드 전달

  27. 27

    낙타 수신자 목록이 메시지를 전달하는 방법

  28. 28

    JMS 메시지 ID는 JMS 서버가 메시지를 수신 한 순서를 나타 냅니까? 메시지 주문 전달

  29. 29

    셀러리는 차단되지 않는 발신자에게 상태 업데이트를 전달할 수 있습니까?

뜨겁다태그

보관