这更像是一种观察,也是对什么是处理这种情况的最佳方式的建议.
我有两个线程,一个只是泵入数据,另一个接收数据,并在发送另一个套接字之前做了很多工作.两个线程都通过域套接字连接.这里使用的协议是UDP.我不想使用TCP,因为它是基于流的,这意味着如果队列中的空间很小,我的数据将被拆分并发送.这是不好的,因为Iam发送不应拆分的数据.因此我使用了DGRAM.有趣的是,当发送线程通过抽取如此多的数据来压倒recv线程时,在某些时候Domain套接字缓冲区被填满并且sendto()返回ENOBUFS.我认为,如果发生这种情况,sendto()将阻塞,直到缓冲区可用.这将是我理想的行为.然而,情况似乎并非如此.我以一种相当奇怪的方式解决了这个问题.
CPU Yield方法如果我得到ENOBUFS,我会做一个sched_yield(); 因为OSX中没有pthread_yield().之后我尝试重新发送.如果失败了,我会一直这样做,直到它被采取.这是糟糕的,因为Iam浪费cpu周期只是做一些无用的东西.如果sendto()被阻止,我会很高兴.
睡眠方法我尝试使用sleep(1)而不是sched_yield()解决相同的问题,但这没有用作sleep()会使我的进程进入睡眠状态而不仅仅是发送线程.
他们两个似乎都不适合我,而且我的选择用完了.有人可以建议处理这个问题的最佳方法是什么?是否有一些巧妙的技巧我不知道可以减少不必要的CPU周期?顺便说一句,那人说:页约sentto()是错误的,在此基础上讨论http://lists.freebsd.org/pipermail/freebsd-hackers/2004-January/005385.html
内核中的Upd代码:
The udp_output function in /sys/netinet/udp_usrreq.c, seems clear:
/*
* Calculate data length and get a mbuf
* for UDP and IP headers.
*/
M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
if (m == 0) {
error = ENOBUFS;
if (addr)
splx(s);
goto release;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试自定义处理由于RAML规范失败而发送给调用者的响应。目前,我的代码执行以下操作。
const cfg = require("./cfg");
const log = require('./logging');
const RAML = require('osprey');
const startMessage = "My Service started on port " + cfg.SERVER_PORT + " at " + cfg.API_MOUNT_POINT;
// start an express server
const start = x => {
// server dependencies
const fs = require('fs'),
express = require('express'),
app = express(),
router = express.Router(),
bodyParser = require('body-parser'),
api = require('./api');
RAML.loadFile(cfg.API_SPEC).then(_raml => {
app.use(bodyParser.json({ extended: true }));
// hide the useless "powered by express" header
app.disable('x-powered-by');
// …Run Code Online (Sandbox Code Playgroud)