socketpair
2017-01-17 16:49
441 查看
socketpair:建立一对匿名的已经连接的套接字
#include <sys/types.h>
#include <sys/socket.h>
int socketpair(int d, int type, int protocol, int sv[2]);
1)UNIX域
2)SOCK_STREAM SOCK_DGRAM
3)对于socketpair函数,protocol参数必须提供为0。
4)参数sv[2]是接收代表两个套接口的整数数组。每一个文件描述符代表一个套接口,并且与另一个并没有区别。
5)返回值:成功时,返回零。 出错时,返回-1,并适当地设置errno。
在ProxyManager的分派连接中,调用ProxyWorker中的send函数
在ProxyWorker中,start函数,父进程send,子进程读
ProxyWorker中的send函数
#include <sys/types.h>
#include <sys/socket.h>
int socketpair(int d, int type, int protocol, int sv[2]);
1)UNIX域
2)SOCK_STREAM SOCK_DGRAM
3)对于socketpair函数,protocol参数必须提供为0。
4)参数sv[2]是接收代表两个套接口的整数数组。每一个文件描述符代表一个套接口,并且与另一个并没有区别。
5)返回值:成功时,返回零。 出错时,返回-1,并适当地设置errno。
在ProxyManager的分派连接中,调用ProxyWorker中的send函数
// 分派连接 for (size_t i = 0; i < _workers.size(); ++i) { int ret = _workers[_idx]->send(&fds[0], (int)fds.size()); _idx = (_idx + 1) % (int)_workers.size(); if (ret == 0) { break; } }
在ProxyWorker中,start函数,父进程send,子进程读
void ProxyWorker::start() { if (_fd != -1) { ::close(_fd); _fd = -1; } int fd[2]; ::socketpair(AF_UNIX, SOCK_STREAM, 0, fd); // 未命名的全双工管道 可以在fd[0] 与 fd[1]间 (父子进程间)完成通讯 if ((_pid = fork()) == 0) { // 子进程 Comm::LogErr("worker %u running", _startId); ::close(fd[0]); _pid = getpid(); { int cpu_num = sysconf(_SC_NPROCESSORS_ONLN) - 1; if (cpu_num > 2){ int cpuidx = (_startId + 1 ) % cpu_num + 1; cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(cpuidx, &mask); sched_setaffinity(_pid, sizeof(mask), &mask); } } _mgr.init(fd[1], _startId, _step); _mgr.run(); Comm::LogErr("worker exit"); _exit(0); } else if (_pid > 0) { // 父进程 ::close(fd[1]); _fd = fd[0]; } else { //Comm::LogErr } }
ProxyWorker中的send函数
int ProxyWorker::send(int* fd, int n) { char c = '\0'; struct iovec iov; iov.iov_base = &c; iov.iov_len = 1; char buf[CMSG_SPACE(sizeof(int) * n)]; struct msghdr msg = { 0 }; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = buf; msg.msg_controllen = sizeof(buf); msg.msg_name = NULL; msg.msg_namelen = 0; struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; cmsg->cmsg_len = CMSG_LEN(sizeof(int) * n); memcpy(CMSG_DATA(cmsg), fd, sizeof(int) * n); ssize_t s = ::sendmsg(_fd, &msg, 0); if (s < 0) { Comm::LogErr("sendmsg %ld %s", s, strerror(errno)); return -1; } return 0; }
相关文章推荐
- Fintech前沿技术周报【2017-1-17】
- BZOJ 3172 [Tjoi2013] 单词 Fail树
- Rails报找不到sanitize和raw方法的解决
- Rails报找不到sanitize和raw方法的解决
- Rails报找不到sanitize和raw方法的解决
- JVM:线程状态park, wait, sleep, interrupt, yeild 对比
- 解决办法:CREATE_LISTENER_FAILED_4异常
- vim 命令大全(写的非常全和好)http://blog.csdn.net/woshixiaosimao/article/details/54312738
- Google 超分辨率技术 RAISR:模糊图片瞬间变清晰,运算速度快十倍
- mongodb停止遇到shutdownServer failed: unauthorized: this command must run from localhost when running db without auth解决方法
- 220. Contains Duplicate III
- install failed with message INSTALL_FAILED_CONFLICTING_PROVIDER 解决方案
- Sync Session Failed to Start(手机和电脑同步失败)
- dubbo+zookeeper报错:com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method
- from: can't read /var/mail/xxx 解决方法
- 有用的 Mongo命令行 db.currentOp() db.collection.find().explain() - 摘自网络
- Linux Top Command Output Explained
- [TypeScript] Simplify asynchronous callback functions using async/await
- No service of type Factory available in ProjectScopeServices
- set容器_find查找_equal_range(pair的使用)