在线有许多基于线程的Web服务器示例,但我还没有真正看到任何能够提供基于事件循环的良好示例(没有非常复杂,例如lighttp和nginx).
有吗?如果没有,我应该阅读/看看什么来帮助我学习如何制作这种服务器?(这包括C中的异步IO等)
我已经理解了基于事件循环的编程如何工作的基础知识,特别是在像Python这样的高级语言中,但我需要能够在C中实现一个.
我有以下使用Node.js的简单http服务器:
var http = require('http');
var server = http.createServer(function(req, res) {
var counter = 0;
for(var i = 1; i <= 30; i++) {
http.get({ host: "www.google.com" }, function(r) {
counter++;
res.write("Response " + counter + ": " + r.statusCode + "\n");
if(counter == 30) res.end();
});
}
});
server.listen(8000);
Run Code Online (Sandbox Code Playgroud)
当我在端口8000上卷入我的本地主机时,我确实得到了预期的结果:
Response 1: 200
Response 2: 200
Response 3: 200
...
Response 30: 200
Run Code Online (Sandbox Code Playgroud)
但是当我在第一个进程运行时尝试从另一个终端卷入时,我看到控制台挂起并等待第一个进程完全完成,然后才开始接收相同的输出.
我的理解是,由于这是使用回调的异步代码,节点可以通过在事件循环的下一个滴答处理它们来同步处理多个请求.事实上,我甚至还观看过Ryan Dahl的视频,其中有一个类似于hello world的例子.我的代码中有什么东西可以阻止服务器阻塞?
在20世纪80年代的Apple II BASIC上,您将使用"HGR"进入屏幕,"HCOLOR"将设置颜色,"HPLOT"将绘制点.您还可以操作屏幕字节数据,而不必将程序控制交给任何事件处理程序.今天,每种语言和每个图书馆似乎都缺少这种荒谬的基本功能.
所以我使用X Window API 在C中编写了一个小型库来执行此操作:HGR(x,y)设置XWindow,HCOLOR(i)设置颜色,HPLOT(i,j)绘制一个点,加上你提取窗口的位图,可以修改它并显示修改过的东西.这不是直截了当的,我不想再次通过它.
我现在正在使用Perl做一些事情,我需要Perl这样的工具,你可以调用一个子程序,最好在没有产生新线程的情况下返回,输出一个窗口,你可以在窗口中添加图形内容,以及在您的程序感觉它时查询事件.这是1980年代BASIC的功能,所以它应该不难.但是我看到的工具没有这样做:
有没有人知道如何从正在运行的应用程序中放置一个XWindow,而不需要一个GUI应用程序进程,在这里您可以在窗口中绘制原始内容,如点和线,以及您可以按照自己的计划查询窗口事件的位置?我简要地看了一下Perl的X Window API,它和C一样可怕,并且将C代码与Perl连接起来也是可怕的.如有必要,我会这样做.但也许不是.Perl有没有HGR?
如果您想知道我的意思,没有事件循环图形库,请参阅此链接文章,遗憾的是C语言.这对于科学的东西非常有用,除了介绍性编程类之外.
我想确认一下我认为Qt中工作线程的直接方面.
假设我创建了一个QThread,其目的是在相应的线程中管理耗时的工作.此外,假设我允许通过调用start()QThread 来运行此线程的相应事件循环.工作本身由一个由QThread started()信号发出信号的成员函数(槽)执行.
那是(从/sf/answers/772745151/复制):
class Task : public QObject
{
Q_OBJECT
public:
Task();
~Task();
public slots:
void doWork()
{
//very time-consuming code is executed here before the next line is reached...
emit workFinished(); // Calls workFinished() signal (after a long time)
}
signals:
void workFinished();
};
// ... in the main thread:
QThread *thread = new QThread( );
Task *task = new Task();
task->moveToThread(thread);
connect( thread, SIGNAL(started()), task, SLOT(doWork()) );
connect( task, SIGNAL(workFinished()), thread, …Run Code Online (Sandbox Code Playgroud) 以下代码只是挂起而没有打印任何东西:
import asyncio
async def foo(loop):
print('foo')
loop.stop()
loop = asyncio.new_event_loop()
asyncio.ensure_future(foo(loop))
loop.run_forever()
Run Code Online (Sandbox Code Playgroud)
如果我使用get_event_loop一切正常.有什么我做错了或我偶然发现了一个错误?
我正在使用Python 3.5.1.
I'm trying to create a function performing some asynchronous operations using asyncio, users of this function should not need to know that asyncio is involved under the hood. I'm having a very hard time understanding how this shall be done with the asyncio API as most functions seem to operate under some global loop-variable accessed with get_event_loop and calls to this are affected by the global state inside this loop.
I have four examples here where two (foo1 and …
人们普遍认为JavaScript本质上是单线程的,但可以异步运行。我想知道像这样的单线程模型如何处理非阻塞的AJAX请求?
假设在浏览器中触发了非阻塞AJAX请求,但没有立即得到响应。如果事件循环不断检查响应,执行是否不会被阻塞?当没有响应时,事件循环是否继续检查其状态并将任务“重新添加”到宏任务队列的后面?
据我了解,Node.js会静默生成线程以处理访问磁盘,数据库,网络套接字等的I / O操作。浏览器中的JavaScript是否也生成线程来处理AJAX?
可能会问类似的问题:
var img = new Image();
img.onerror=function(){alert('error: '+this.src);}
img.onload=function(){alert('image loaded: '+this.src);}
img.src='path/to/image.jpg';
Run Code Online (Sandbox Code Playgroud)
上面的代码的最后一行是否由于该语句似乎是非阻塞的而导致产生了另一个线程?
我一直看到"Javascript事件循环"(即:浏览器JS运行时事件循环)的解释对我来说似乎不合理,我希望有人可以提供一些权威的澄清.
我的基本假设是JS事件循环就像我们几十年来一直在UI框架中使用的事件循环,如:
// [... some initialization ...]
// The Event Loop
while (true) {
if (! EventQueue.isEmpty()) {
event = EventQueue.pop_oldest_item();
event.callback(event [or some other kind of args]);
}
// [... defer to other non-JS tasks...]
}
Run Code Online (Sandbox Code Playgroud)
但我一直在看这样的解释(见下面的例子):
事件循环:
检查(Javascript)调用堆栈是否为空.
检查回调队列[AKA EventQueue]是否为空.
如果调用堆栈为空并且回调队列不为空,则:
一个.将最旧的回调队列项出列.
湾 将该回调函数推送到调用堆栈(并且没有提到调用该函数.)
保持循环.
这显然模糊地遵循我上面假设的模型,但有两个关键和令人不安的差异:
A.为什么事件循环需要检查JS调用堆栈是否为空?当然,每次循环时,调用堆栈都将处于相同的状态(无论是否完全"空"是在点之外 - 它不需要"检查").无论上次调用什么函数都会返回,恢复堆栈.所以那部分毫无意义.
B.为什么事件循环"将回调推送到JS堆栈"?事件循环不应该只是调用函数,从而创建一个合法的堆栈帧,以及从函数返回的方法,更不用说实际执行函数了吗?
所以我希望得到澄清,解释这些解释以及为什么它们实际上是正确的,或者支持我强烈怀疑它们是不正确的.
这些事件循环说明的示例来源:
菲利普罗伯茨:无论如何,事件循环到底是什么?在14:00 https://youtu.be/8aGhZQkoFbQ?t=839
打字稿高性能(书)第83页.
什么是Javascript事件循环? http://altitudelabs.com/blog/what-is-the-javascript-event-loop/
了解Javascript函数执行 - 调用堆栈,事件循环,任务及更多内容 https://medium.com/@gaurav.pandvia/understanding-javascript-function-executions-tasks-event-loop-call-stack-more-part-1 -5683dea1f5ec
该事件循环文档中提到event_loop_policy,但没有描述它是什么,为什么需要将详细介绍这个抽象层。(文档甚至说可以自定义这一层)。
另外,help(asyncio.get_event_loop_policy())只是说...
带有子进程观察器的 UNIX 事件循环策略。
然后,我就更糊涂了。什么是watcher?什么是child processes中event loop?
我正在尝试编写一个执行可中断计算的网络工作者。Worker.terminate()我知道这样做的唯一方法(除了)是定期让步给消息循环,以便它可以检查是否有任何新消息。例如,这个网络工作者计算从 0 到 的整数之和data,但是如果您在计算过程中向它发送一条新消息,它将取消计算并开始新的计算。
let currentTask = {
cancelled: false,
}
onmessage = event => {
// Cancel the current task if there is one.
currentTask.cancelled = true;
// Make a new task (this takes advantage of objects being references in Javascript).
currentTask = {
cancelled: false,
};
performComputation(currentTask, event.data);
}
// Wait for setTimeout(0) to complete, so that the event loop can receive any pending messages.
function yieldToMacrotasks() {
return new Promise((resolve) => setTimeout(resolve));
} …Run Code Online (Sandbox Code Playgroud) event-loop ×10
javascript ×4
python ×3
python-3.5 ×2
python-3.x ×2
ajax ×1
asynchronous ×1
c ×1
c++ ×1
event-driven ×1
evented-io ×1
events ×1
graphics ×1
node.js ×1
nonblocking ×1
perl ×1
qt ×1
settimeout ×1
web-worker ×1