mirror of
https://github.com/opencontainers/runc.git
synced 2026-11-06 05:17:05 +00:00
performance improvement: setup signal notify in a new go routine
There is a big loop(at least 65 times) in `signal.Notify`, it costs as much time as `runc init`, so we can call it in parallel ro reduce the container start time. In a general test, it can be reduced about 38.70%. Signed-off-by: lifubang <lifubang@acmcoder.com> (cyphar: move signal channel definition inside goroutine) Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
This commit is contained in:
1 parent
202ca99fae
commit
d92dd22611
2 files changed
+20
-11
No files matched your search
+18
-10
@@ -18,22 +18,30 @@ const signalBufferSize = 2048
|
|||||||
// while still forwarding all other signals to the process.
|
// while still forwarding all other signals to the process.
|
||||||
// If notifySocket is present, use it to read systemd notifications from the container and
|
// If notifySocket is present, use it to read systemd notifications from the container and
|
||||||
// forward them to notifySocketHost.
|
// forward them to notifySocketHost.
|
||||||
func newSignalHandler(enableSubreaper bool, notifySocket *notifySocket) *signalHandler {
|
func newSignalHandler(enableSubreaper bool, notifySocket *notifySocket) chan *signalHandler {
|
||||||
if enableSubreaper {
|
if enableSubreaper {
|
||||||
// set us as the subreaper before registering the signal handler for the container
|
// set us as the subreaper before registering the signal handler for the container
|
||||||
if err := system.SetSubreaper(1); err != nil {
|
if err := system.SetSubreaper(1); err != nil {
|
||||||
logrus.Warn(err)
|
logrus.Warn(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ensure that we have a large buffer size so that we do not miss any signals
|
handler := make(chan *signalHandler)
|
||||||
// in case we are not processing them fast enough.
|
// signal.Notify is actually quite expensive, as it has to configure the
|
||||||
s := make(chan os.Signal, signalBufferSize)
|
// signal mask and add signal handlers for all signals (all ~65 of them).
|
||||||
// handle all signals for the process.
|
// So, defer this to a background thread while doing the rest of the io/tty
|
||||||
signal.Notify(s)
|
// setup.
|
||||||
return &signalHandler{
|
go func() {
|
||||||
signals: s,
|
// ensure that we have a large buffer size so that we do not miss any
|
||||||
notifySocket: notifySocket,
|
// signals in case we are not processing them fast enough.
|
||||||
}
|
s := make(chan os.Signal, signalBufferSize)
|
||||||
|
// handle all signals for the process.
|
||||||
|
signal.Notify(s)
|
||||||
|
handler <- &signalHandler{
|
||||||
|
signals: s,
|
||||||
|
notifySocket: notifySocket,
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// exit models a process exit status with the pid and
|
// exit models a process exit status with the pid and
|
||||||
|
|||||||
+2
-1
@@ -246,7 +246,7 @@ func (r *runner) run(config *specs.Process) (int, error) {
|
|||||||
// Setting up IO is a two stage process. We need to modify process to deal
|
// Setting up IO is a two stage process. We need to modify process to deal
|
||||||
// with detaching containers, and then we get a tty after the container has
|
// with detaching containers, and then we get a tty after the container has
|
||||||
// started.
|
// started.
|
||||||
handler := newSignalHandler(r.enableSubreaper, r.notifySocket)
|
handlerCh := newSignalHandler(r.enableSubreaper, r.notifySocket)
|
||||||
tty, err := setupIO(process, r.container, config.Terminal, detach, r.consoleSocket)
|
tty, err := setupIO(process, r.container, config.Terminal, detach, r.consoleSocket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
@@ -285,6 +285,7 @@ func (r *runner) run(config *specs.Process) (int, error) {
|
|||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
handler := <-handlerCh
|
||||||
status, err := handler.forward(process, tty, detach)
|
status, err := handler.forward(process, tty, detach)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.terminate(process)
|
r.terminate(process)
|
||||||
|
|||||||
Reference in new issue
Block a user