추상화가 서로 다른 수준에 있기 때문에 채널과 파일 설명자를 모두 선택할 수 없습니다. 채널은 운영 체제에서 go 런타임 및 파일 설명자에 의해 처리됩니다. 당신이 필요로하는 것은 그들 사이에 다리를 만드는 것입니다.이 작업은 net.Pipe()
으로 할 수 있습니다.
거의 당신이해야 할 일을 당신의 zmq-소켓과 하나의 "일어나"net.Pipe()
을 볼 수 epoll()
/select()
하나의 goroutine을 바치고있다. 여론 조사 서버입니다. 다른 goroutine은 읽기 및 쓰기 채널을 수신합니다. 누군가가 읽기 또는 쓰기 채널을 전송하면 두 번째 goroutine이 파이프를 보내어 폴링 서버를 시작합니다.
표준 라이브러리의 넷 패키지가 작동하는 방식입니다. 영감을 얻기 위해 그것을 읽는 것이 좋습니다 (또는 BSD 라이센스가 매우 자유주의입니다).
다음은 pollServer from net 자체에 대한 설명입니다. 이 코드의 의미를 이해하려면 코드를 읽어야하지만, fd.go
의이 섹션은 시작하기에 좋은 장소 여야합니다.
// A pollServer helps FDs determine when to retry a non-blocking
// read or write after they get EAGAIN. When an FD needs to wait,
// send the fd on s.cr (for a read) or s.cw (for a write) to pass the
// request to the poll server. Then receive on fd.cr/fd.cw.
// When the pollServer finds that i/o on FD should be possible
// again, it will send fd on fd.cr/fd.cw to wake any waiting processes.
// This protocol is implemented as s.WaitRead() and s.WaitWrite().
//
// There is one subtlety: when sending on s.cr/s.cw, the
// poll server is probably in a system call, waiting for an fd
// to become ready. It's not looking at the request channels.
// To resolve this, the poll server waits not just on the FDs it has
// been given but also its own pipe. After sending on the
// buffered channel s.cr/s.cw, WaitRead/WaitWrite writes a
// byte to the pipe, causing the pollServer's poll system call to
// return. In response to the pipe being readable, the pollServer
// re-polls its request channels.
//
// Note that the ordering is "send request" and then "wake up server".
// If the operations were reversed, there would be a race: the poll
// server might wake up and look at the request channel, see that it
// was empty, and go back to sleep, all before the requester managed
// to send the request. Because the send must complete before the wakeup,
// the request channel must be buffered. A buffer of size 1 is sufficient
// for any request load. If many processes are trying to submit requests,
// one will succeed, the pollServer will read the request, and then the
// channel will be empty for the next process's request. A larger buffer
// might help batch requests.
//
// To avoid races in closing, all fd operations are locked and
// refcounted. when netFD.Close() is called, it calls syscall.Shutdown
// and sets a closing flag. Only when the last reference is removed
// will the fd be closed.
행운을 다시 빕니다. 이 모든 zmq-socket의 끝 부분에있는 좋은 소식은 쓰레드가 안전 할 것입니다.
호기심을 위해서만 https://github.com/duckie/boson과 같은 다른 프로젝트에서 할 수있는 일입니다. –