Каково различие между nohup и демоном?

Как описано в моего ответа - Как выполнить модульный тест GetNewValues ​​(), который содержит функцию EntityFunctions.AddDays , вы можете использовать посетитель выражения запроса для замены вызовов функций EntityFunctions с вашими собственными реализациями, совместимыми с LINQ To Objects.

Реализация будет выглядеть так:

using System;
using System.Data.Objects;
using System.Linq;
using System.Linq.Expressions;

static class EntityFunctionsFake
{
    public static DateTime? TruncateTime(DateTime? original)
    {
        if (!original.HasValue) return null;
        return original.Value.Date;
    }
}
public class EntityFunctionsFakerVisitor : ExpressionVisitor
{
    protected override Expression VisitMethodCall(MethodCallExpression node)
    {
        if (node.Method.DeclaringType == typeof(EntityFunctions))
        {
            var visitedArguments = Visit(node.Arguments).ToArray();
            return Expression.Call(typeof(EntityFunctionsFake), node.Method.Name, node.Method.GetGenericArguments(), visitedArguments);
        }

        return base.VisitMethodCall(node);
    }
}
class VisitedQueryProvider : IQueryProvider
    where TVisitor : ExpressionVisitor, new()
{
    private readonly IQueryProvider _underlyingQueryProvider;
    public VisitedQueryProvider(IQueryProvider underlyingQueryProvider)
    {
        if (underlyingQueryProvider == null) throw new ArgumentNullException();
        _underlyingQueryProvider = underlyingQueryProvider;
    }

    private static Expression Visit(Expression expression)
    {
        return new TVisitor().Visit(expression);
    }

    public IQueryable CreateQuery(Expression expression)
    {
        return new VisitedQueryable(_underlyingQueryProvider.CreateQuery(Visit(expression)));
    }

    public IQueryable CreateQuery(Expression expression)
    {
        var sourceQueryable = _underlyingQueryProvider.CreateQuery(Visit(expression));
        var visitedQueryableType = typeof(VisitedQueryable<,>).MakeGenericType(
            sourceQueryable.ElementType,
            typeof(TVisitor)
            );

        return (IQueryable)Activator.CreateInstance(visitedQueryableType, sourceQueryable);
    }

    public TResult Execute(Expression expression)
    {
        return _underlyingQueryProvider.Execute(Visit(expression));
    }

    public object Execute(Expression expression)
    {
        return _underlyingQueryProvider.Execute(Visit(expression));
    }
}
public class VisitedQueryable : IQueryable
    where TExpressionVisitor : ExpressionVisitor, new()
{
    private readonly IQueryable _underlyingQuery;
    private readonly VisitedQueryProvider _queryProviderWrapper;
    public VisitedQueryable(IQueryable underlyingQuery)
    {
        _underlyingQuery = underlyingQuery;
        _queryProviderWrapper = new VisitedQueryProvider(underlyingQuery.Provider);
    }

    public IEnumerator GetEnumerator()
    {
        return _underlyingQuery.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public Expression Expression
    {
        get { return _underlyingQuery.Expression; }
    }

    public Type ElementType
    {
        get { return _underlyingQuery.ElementType; }
    }

    public IQueryProvider Provider
    {
        get { return _queryProviderWrapper; }
    }
}

А вот пример использования с TruncateTime:

var linq2ObjectsSource = new List() { null }.AsQueryable();
var visitedSource = new VisitedQueryable(linq2ObjectsSource);
// If you do not use a lambda expression on the following line,
// The LINQ To Objects implementation is used. I have not found a way around it.
var visitedQuery = visitedSource.Select(dt => EntityFunctions.TruncateTime(dt));
var results = visitedQuery.ToList();
Assert.AreEqual(1, results.Count);
Assert.AreEqual(null, results[0]);

57
задан Trott 20 September 2011 в 20:00
поделиться

3 ответа

Команда nohup - это плохой способ запустить процесс как демон. Как заметил Бруно Раншарт, когда вы запускаете команду в интерактивной оболочке, она имеет управляющий терминал и будет получать сигнал SIGHUP (зависание), когда контролирующий процесс (обычно ваша оболочка входа) завершается. Команда nohup упорядочивает входные данные из / dev / null , а для вывода и ошибок - в nohup.out , а для программы - игнорировать прерывания, сигналы выхода и зависания. На самом деле он имеет тот же управляющий терминал - он просто игнорирует элементы управления терминалом. Обратите внимание: если вы хотите, чтобы процесс выполнялся в фоновом режиме, вы должны указать оболочке запускать его в фоновом режиме - по крайней мере, в Solaris (то есть вы набираете ' nohup sleep 20 & »; без амперсанда процесс выполняется синхронно на переднем плане).

Как правило, процесс, выполняемый через nohup , требует времени, но который не стоит ждать взаимодействия откуда-то еще.

Обычно (что означает, что если вы очень постараетесь, вы можете найти исключения из этих правил), процесс-демон - это что-то, что скрывается в фоновом режиме, отключено от любого терминала, но ожидает ответа на какой-либо ввод. Сетевые демоны ждут запросов на соединение или сообщений UDP, которые поступят по сети, выполняют соответствующую работу и снова отправляют ответ. Представьте, например, веб-сервер или СУБД.

Когда процесс полностью демонизирует себя, он выполняет некоторые из шагов, которые выполняет код nohup ; он перестраивает свой ввод / вывод так, чтобы он не был подключен к какому-либо терминалу, отделяется от группы процессов, игнорирует соответствующие сигналы (что может означать, что он не игнорирует никакие сигналы, поскольку нет терминала для отправки ему сигналов, генерируемых через терминал). Обычно он разветвляется один раз, и родитель успешно завершает работу. Дочерний процесс обычно разветвляется второй раз после исправления группы процессов, идентификатора сеанса и т. Д. затем ребенок тоже уходит. Внук-процесс теперь автономен и не будет отображаться в выводе ps для терминала, на котором он был запущен.

Вы можете посмотреть Advanced Programming in the Unix Environment, 3rd Edn Ричард Стивенс и Стивен Раго, или на Advanced Unix Programming, 2nd Edn Марк Дж. Рочкинд для обсуждения демонизации.

У меня есть программа daemonize , которая будет демонизировать программу, которая не знает, как демонизировать себя (правильно). Он был написан для устранения дефектов в программе, которая должна была демонстрировать себя, но не выполняла свою работу должным образом. Свяжитесь со мной, если хотите - см. Мой профиль.

72
ответ дан 24 November 2019 в 19:29
поделиться

В вариантах UNIX процесс связан с конечным процессом (оболочкой входа). Поэтому, когда завершается процесс терминала, он также останавливается из-за этой связи. Nohup предотвращает завершение процесса при остановке терминала.

Демон или демон - это процесс, который запускается системой при запуске, он работает до завершения работы, ни один пользователь не запрашивал его явно. Таким образом, по определению он не является частью взаимодействия с пользователем, но принадлежит системе.

Если у вас есть доступ к системе как пользователь, вы можете использовать nohup. Если вы системный администратор, вы можете установить процесс демона. Для процесса это не имеет значения.

8
ответ дан 24 November 2019 в 19:29
поделиться

Демон не может быть инициирован, в то время как nohup инициируется пользователем.

-1
ответ дан 24 November 2019 в 19:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: