一直在努力学习Docker,让我感到困惑的一件事就是如何在Docker容器中实际运行不同版本的Linux(到主机操作系统).
如果我们假设我的Docker主机正在运行RedHat并且我从Ubuntu映像启动一个容器,则以下是真的吗?:
我知道Docker容器共享主机操作系统使用的相同内核,Docker的一个基本点是使用底层操作系统的容器效率提升.所以我对启动从不同于主机的Linux版本创建的Container时实际发生的事情感到困惑.
在计算的同步/阻塞模型中,我们通常说执行线程在等待IO任务完成时将等待(被阻塞).
我的问题是,这通常会导致CPU核心执行线程空闲,还是等待IO的线程通常会被上下文切换出来并进入等待状态,直到IO准备好被处理?
multithreading asynchronous cpu-architecture synchronous blocking
看了几个其他的问题,但没有找到我想要的东西.我使用Scala,但我的问题非常高,所以希望任何语言都是不可知的.
常规场景:
Thread A 运行一个函数,有一些阻塞工作要做(比如一个DB调用).Async,Scala中的块),以使某种"工作者" Thread B(在不同的池中)获取I/O任务.Thread A完成返回一个Future,它最终将包含结果并Thread A返回到其池中以快速获取另一个要处理的请求.Q1.有些线程通常需要等待?
我对非阻塞体系结构的理解是,常见的方法是在I/O工作的某个地方仍然有一些线程等待/阻塞 - 它只是一个具有不同池的访问不同内核以便少量请求的情况处理线程可以管理大量并发请求,而无需等待CPU核心.
这是正确的一般理解吗?
Q2.回调如何运作?
在上面的场景中 - Thread B如果/当I/O工作完成时,I/O工作将运行回调函数(由线程A提供) - 这完成了Future一些Result.
线程A现在正在执行其他操作,并且不再与原始请求关联.未来的结果如何被发送回客户端套接字?我知道不同的语言有不同的这种机制的实现,但在很高的层次上,我目前的假设是(不管语言/框架)一些框架/容器对象必须始终做某种编排,以便当Future任务是完成后,Result将被发送回处理请求的原始套接字.
我花了几个小时试图找到可以解释这个问题的文章,但每篇文章似乎只是处理真正的低级细节.我知道我错过了一些细节,但我很难问我的问题,因为我不太确定我错过了哪些部分:)
我试图了解HTTP服务器如何确保将正确的响应发送回正确的客户端。
在很高的水平上:
在服务器实现的TCP层,一些ServerSocket(在侦听请求的主机:端口上侦听)创建了一个“客户端套接字”来处理请求
(如果我们假设它是线程服务器)-在应用程序中分配了一个线程,工作就完成了
问题:-
A.)响应是否必须返回与处理请求的套接字相同的套接字?
B.)如果是,响应如何映射到处理请求的同一套接字?
C.)套接字是维护响应数据包需要发送回去的客户端IP /主机的责任,还是HTTP标头来维护此信息,然后将其用于将响应寻址回正确的客户端?
如果HTTP标头信息用于将响应路由回调用方客户端,则我认为响应不一定必须由处理关联请求的同一套接字处理
任何帮助深表感谢。詹姆士
我认为我对Monads和monadic操作有一个基本的把握,但仍然有点停留在理解monadic类型的神奇特征如何被添加到底层类型(希望这是有道理的).
例如,我正在阅读有关a List[T]是monad的信息.但是,如果我flatMap和map一些列表依次在一个for理解中,那么它是不是真的flatMap,map那提供了monadic魔法?
如果我创造了一个List<String>那么monadic魔法是如何添加的?或者List<T>在Scala中始终是一个monad,因为它恰好是语言已经提供内置monadic支持的那些容器之一?
我知道,val是不是final,除非显式声明所以并使用javap的确认Scalac没有插入final到字节码.
val因为编译器阻止我们编写任何试图改变它的代码,所以是不可变的吗?
我是斯卡拉新手,我认为它是一种非常丰富的语言.让我抓住语法的一件事就是功能创建.我知道大括号{}被编译器解释为在许多上下文中与括号()同义,但以下我仍然不太明白.
以下是Scala REPL的输出:
scala> def index = List {}
index: List[Unit]
scala> def index = List ()
index: List[Nothing]
Run Code Online (Sandbox Code Playgroud)
Q1.
如果我正确地理解了上述内容,我正在创建一个名为的函数index,它创建一个新的List(new由于对apply方法的隐式调用而被省略?).
我看到Unit(相当于null在Java中?)是使用大括号{}时的列表类型.但是使用parens()时没有什么类型.
Q2.
有人可以用简单的术语(如果可能的话)解释使用{}和()创建函数之间的区别以及Nothing代表什么?
编辑 - 所以以下是等价的?
def index = List {val a = 1; a}
def index = List ({val a = 1; a})
Run Code Online (Sandbox Code Playgroud)
我也在与术语的位置有点挣扎function,method似乎可以互换使用.
说上述两者都可以被认为是a function还是method?是正确的吗?或者它取决于你与谁交谈?
我很可能没有For恰当地使用理解,但我认为我的问题相对普遍.我Futures在Play Action中创建了两个.
即使我可以Future在for它们之外实例化它们以给它们并行运行的机会,但我希望它们按顺序排列,因为我只想在缓存中找到第二个Future(Web服务调用)value.
for {
value <- getValueFromCache // Future[Option[String]]
wsResponse <- callWebService(value) // Future[WSResponse]
} yield wsResponse
Run Code Online (Sandbox Code Playgroud)
我的问题
当我执行上面的操作,并且value在缓存中找不到时,仍然创建/执行第二个Future(Web服务调用) - 这是我不想要的.
我对理解的for理解是,即使第二个任务不直接依赖于第一个任务,第二个任务只有在第一个任务成功完成时才会运行.
如果value在缓存中找不到,value = None.
这是为什么第二个Future仍然被创建/执行 - 因为None仍然被认为是第一个成功完成Future?
在什么情况下第二个Future不会被创建 - 如果且仅当第一个Future完成时Exception?
我正在考虑使用一种if 1st not complete properly then do not continue陈述,但这仍然让我理解如何for处理一个很大的差距.
scala ×5
asynchronous ×2
blocking ×1
callback ×1
docker ×1
function ×1
http ×1
monads ×1
nonblocking ×1
sockets ×1
synchronous ×1
tcp ×1