您的位置:首页 > 大数据 > 人工智能

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函数

// 分派连接
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: