C init что это за программа

Конструктор класса – метод __init__()

В объектно-ориентированном программировании конструктором класса называют метод, который автоматически вызывается при создании объектов. Его также можно назвать конструктором объектов класса. Имя такого метода обычно регламентируется синтаксисом конкретного языка программирования. Так в Java имя конструктора класса совпадает с именем самого класса. В Python же роль конструктора играет метод __init__().

В Python наличие пар знаков подчеркивания спереди и сзади в имени метода говорит о том, что он принадлежит к группе методов перегрузки операторов. Если подобные методы определены в классе, то объекты могут участвовать в таких операциях как сложение, вычитание, вызываться как функции и др.

При этом методы перегрузки операторов не надо вызывать по имени. Вызовом для них является сам факт участия объекта в определенной операции. В случае конструктора класса – это операция создания объекта. Так как объект создается в момент вызова класса по имени, то в этот момент вызывается метод __init__().

Init-only свойства — C# 9, .NET 5

Необходимость конструкторов связана с тем, что нередко объекты должны иметь собственные свойства сразу. Пусть имеется класс Person, объекты которого обязательно должны иметь имя и фамилию. Если класс будет описан подобным образом

class Person: def set_name(self, n, s): self.name = n self.surname = s

то создание объекта возможно без полей. Для установки имени и фамилии метод set_name() нужно вызывать отдельно:

>>> from test import Person >>> p1 = Person() >>> p1.set_name(«Bill», «Ross») >>> p1.name, p1.surname (‘Bill’, ‘Ross’)

В свою очередь, конструктор класса не позволит создать объект без обязательных полей:

class Person: def __init__(self, n, s): self.name = n self.

surname = s p1 = Person(«Sam», «Baker») print(p1.name, p1.surname)

Здесь при вызове класса в круглых скобках передаются значения, которые будут присвоены параметрам метода __init__(). Первый его параметр – self – ссылка на сам только что созданный объект.

Теперь, если мы попытаемся создать объект, не передав ничего в конструктор, то будет возбуждено исключение, и объект не будет создан:

>>> p1 = Person() Traceback (most recent call last): File «», line 1, in TypeError: __init__() missing 2 required positional arguments: ‘n’ and ‘s’

Однако бывает, что надо допустить создание объекта, даже если никакие данные в конструктор не передаются. В таком случае параметрам конструктора класса задаются значения по умолчанию:

class Rectangle: def __init__(self, w=0.5, h=1): self.width = w self.

height = h def square(self): return self.width * self.

height rec1 = Rectangle(5, 2) rec2 = Rectangle() rec3 = Rectangle(3) rec4 = Rectangle(h=4) print(rec1.square()) print(rec2.

square()) print(rec3.square()) print(rec4.square())
10 0.5 3 2.0

Если класс вызывается без значений в скобках, то для параметров будут использованы их значения по умолчанию. Однако поля width и height будут у всех объектов.

Передача параметров в функцию по указателю c++. Передача указателя в функцию си. Урок #48

Кроме того, конструктору вовсе не обязательно принимать какие-либо параметры, не считая self. Значения полям могут назначаться как угодно. Также не обязательно, чтобы в конструкторе происходила установка атрибутов объекта. Там может быть, например, код, который порождает создание объектов других классов.

В других языка программирования, например в Java, классы могут содержать несколько конструкторов, которые между собой отличаются количеством параметром, а также, возможно, их типом. При создании объекта срабатывает тот конструктор, количество и типы параметров которого совпали с количеством и типами переданных в конструктор аргументов.

В Python создать несколько методов __init__() в классе можно, однако «рабочим» останется только последний. Он переопределит ранее определенные. Поэтому в Python в классах используется только один конструктор, а изменчивость количества передаваемых аргументов настраивается через назначение значений по-умолчанию.

Практическая работа. Конструктор и деструктор

Помимо конструктора объектов в языках программирования есть обратный ему метод – деструктор. Он вызывается, когда объект не создается, а уничтожается.

В языке программирования Python объект уничтожается, когда исчезают все связанные с ним переменные или им присваивается другое значение, в результате чего связь со старым объектом теряется. Удалить переменную можно с помощью команды языка del.

В классах Python функцию деструктора выполняет метод __del__().

Напишите программу по следующему описанию:

  1. Есть класс Person, конструктор которого принимает три параметра (не учитывая self) – имя, фамилию и квалификацию специалиста. Квалификация имеет значение заданное по умолчанию, равное единице.
  2. У класса Person есть метод, который возвращает строку, включающую в себя всю информацию о сотруднике.
  3. Класс Person содержит деструктор, который выводит на экран фразу «До свидания, мистер …» (вместо троеточия должны выводиться имя и фамилия объекта).
  4. В основной ветке программы создайте три объекта класса Person. Посмотрите информацию о сотрудниках и увольте самое слабое звено.
  5. В конце программы добавьте функцию input(), чтобы скрипт не завершился сам, пока не будет нажат Enter. Иначе вы сразу увидите как удаляются все объекты при завершении работы программы.

В Python деструктор используется редко, так как интерпретатор и без него хорошо убирает «мусор».

Курс с примерами решений практических работ:
pdf-версия, android-приложение

X Скрыть Наверх

Объектно-ориентированное программирование на Python

Источник: younglinux.info

C init что это за программа

Эта глава описывает процесс init , который является первым процессом уровня пользователя, запускаемым ядром. init имеет много важных режимов работы, таких как запуск getty (чтобы пользователи могли войти в систему), изменение уровня выполнения системы и удаление ненужных процессов. Эта глава объясняет как настроить init и как можно менять и использовать различные уровни выполнения.

init является одной из тех программ, которые абсолютно необходимы для системы Linux, но это Вы обычно можете игнорировать. Хороший дистрибутив Linux поставляется с настройками для init , которые подходят для большинства систем. В таком случае Вам не придется что-либо настраивать самому. Вам придется заниматься настройкой init если Вы используете последовательные терминалы (хотя сейчас ими уже никто не пользуется), dial-in (не dial-out) модемы, или меняете настройки уровней выполнения, что вообще-то нужно редко.

Когда ядро запущено (загружено в память, получило управление и инициализировало все драйверы устройств и структуры), оно запускает программу уровня пользователя. Первой такой программой всегда является именно init . Таким образом, init всегда является первым процессом (номер процесса всегда 1).

Ядро ищет init в нескольких местах, в которых он располагается по традиции. В Linux обычно используется имя /sbin/init . Если ядро не нашло init , оно пробует запустить /bin/sh . Если и тут происходит неудача, система выдает ошибку и останавливается.

Когда init запущен, он завершает процесс загрузки системы и выполняет ряд административных задач, таких как проверка файловых систем, очистка каталога /tmp , запуск различных сервисов и запуск процесса getty для каждого терминала и виртуальной консоли откуда пользователи могут входить в систему (см. главу 8 о регистрации пользователей и входе в систему).

После нормального запуска системы init перезапускает getty для каждого терминала после того, как пользователь завершил работу с системой (чтобы следующий пользователь мог зарегистрироваться в системе). init также перехватывает ничейные процессы: когда процесс запускает порожденный процесс и завершает работу до своего потомка, его потомок немедленно становится порожденным из init . Это важно по различным техническим причинам. Вам следует знать это чтобы понять списки процессов и графы дерева процессов. Имеется несколько вариантов init . Большинство дистрибутивов Linux используют sysvinit (написал Miquel van Smoorenburg), который основан на System V init . BSD версии Unix имеют отличия в процессе init . Главным различием являются уровни выполнения: System V имеет их, а BSD нет (по крайней мере, обычно). Мы будем рассматривать только sysvinit .

Источник: www.opennet.ru

C init что это за программа

Кроме обычных методов в языке C# предусмотрены специальные методы доступа, которые называют свойства . Они обеспечивают простой доступ к полям классов и структур, узнать их значение или выполнить их установку.

Определение свойств

Стандартное описание свойства имеет следующий синтаксис:

[модификаторы] тип_свойства название_свойства < get < действия, выполняемые при получении значения свойства>set < действия, выполняемые при установке значения свойства>>

Вначале определения свойства могут идти различные модификаторы, в частности, модификаторы доступа. Затем указывается тип свойства, после которого идет название свойства. Полное определение свойства содержит два блока: get и set .

В блоке get выполняются действия по получению значения свойства. В этом блоке с помощью оператора return возвращаем некоторое значение.

В блоке set устанавливается значение свойства. В этом блоке с помощью параметра value мы можем получить значение, которое передано свойству.

Читайте также:
Что за программа netsh

Блоки get и set еще называются акссесорами или методами доступа (к значению свойства), а также геттером и сеттером.

То есть по сути свойство ничего не хранит, оно выступает в роли посредника между внешним кодом и переменной name.

Person person = new Person(); // Устанавливаем свойство — срабатывает блок Set // значение «Tom» и есть передаваемое в свойство value person.Name = «Tom»; // Получаем значение свойства и присваиваем его переменной — срабатывает блок Get string personName = person.Name; Console.WriteLine(personName); // Tom class Person < private string name = «Undefined»; public string Name < get < return name; // возвращаем значение свойства >set < name = value; // устанавливаем новое значение свойства >> >

Здесь в классе Person определено приватное поле name , которая хранит имя пользователя, и есть общедоступное свойство Name . Хотя они имеют практически одинаковое название за исключением регистра, но это не более чем стиль, названия у них могут быть произвольные и не обязательно должны совпадать.

Через это свойство мы можем управлять доступом к переменной name . В свойстве в блоке get возвращаем значение поля:

А в блоке set устанавливаем значение переменной name. Параметр value представляет передаваемое значение, которое передается переменной name.

В программе мы можем обращаться к этому свойству, как к обычному полю. Если мы ему присваиваем какое-нибудь значение, то срабатывает блок set , а передаваемое значение передается в параметр value :

person.Name = «Tom»;

Если мы получаем значение свойства, то срабатывает блок get , который по сути возвращает значение переменной name:

string personName = p.Name;

Возможно, может возникнуть вопрос, зачем нужны свойства, если мы можем в данной ситуации обходиться обычными полями класса? Но свойства позволяют вложить дополнительную логику, которая может быть необходима при установке или получении значения. Например, нам надо установить проверку по возрасту:

Person person = new Person(); Console.WriteLine(person.Age); // 1 // изменяем значение свойства person.Age = 37; Console.WriteLine(person.Age); // 37 // пробуем передать недопустимое значение person.Age = -23; // Возраст должен быть в диапазоне от 1 до 120 Console.WriteLine(person.Age); // 37 — возраст не изменился class Person < int age = 1; public int Age < set < if (value < 1 || value >120) Console.WriteLine(«Возраст должен быть в диапазоне от 1 до 120»); else age = value; > get < return age; >> >

В данном случае переменная age хранит возраст пользователя. Напрямую мы не можем обратиться к этой переменной — только через свойство Age. Причем в блоке set мы устанавливаем значение, если оно соответствует некоторому разумному диапазону. Поэтому при передаче свойству Age значения, которое не входит в этот диапазон, значение переменной не будет изменяться:

person.Age = -23; Консольный вывод программы: 1 37 Возраст должен быть в диапазоне от 1 до 120 37

Таким образом, свойство позволяет опосредовать и контролировать доступ к данным объекта.

Свойства только для чтения и записи

Блоки set и get не обязательно одновременно должны присутствовать в свойстве. Если свойство определяет только блок get , то такое свойство доступно только для чтения — мы можем получить его значение, но не установить.

И, наоборот, если свойство имеет только блок set , тогда это свойство доступно только для записи — можно только установить значение, но нельзя получить:

Person person = new Person(); // свойство для чтения — можно получить значение Console.WriteLine(person.Name); // Tom // но нельзя установить // person.Name = «Bob»; // ! Ошибка // свойство для записи — можно устновить значение person.Age = 37; // но нелзя получить // Console.WriteLine(person.Age); // ! Ошибка person.Print(); class Person < string name = «Tom»; int age = 1; // свойство только для записи public int Age < set < age = value; >> // свойство только для чтения public string Name < get < return name; >> public void Print()=> Console.WriteLine($»Name: Age: «); >

Здесь свойство Name доступно только для чтения, поскольку оно имеет только блок get :

public string Name < get < return name; >>

Мы можем получить его значение, но НЕ можем установить:

Console.WriteLine(person.Name); // получить можно person.Name = «Bob»; // ! Ошибка — установить нельзя

А свойство Age, наоборот, доступно только для записи, поскольку оно имеет только блок set :

public int Age < set < age = value; >>

Можно установить его значение, но нельзя получить:

person.Age = 37; // установить можно Console.WriteLine(person.Age); // ! Ошибка — получить значение нельзя

Вычисляемые свойства

Свойства необзательно связаны с определенной переменной. Они могут вычисляться на основе различных выражений

Person tom = new(«Tom», «Smith»); Console.WriteLine(tom.Name); // Tom Smith class Person < string firstName; string lastName; public string Name < get < return $»»; > > public Person(string firstName, string lastName) < this.firstName = firstName; this.lastName = lastName; >>

В данном случае класс Person имеет свойство Name, которое доступно только для чтения и которое возвращает общее значение на основе значений переменных firstName и lastName.

Модификаторы доступа

Мы можем применять модификаторы доступа не только ко всему свойству, но и к отдельным блокам get и set:

Person tom = new(«Tom»); // Ошибка — set объявлен с модификатором private //tom.Name = «Bob»; Console.WriteLine(tom.Name); // Tom class Person < string name = «»; public string Name < get < return name; >private set < name = value; >> public Person(string name) => Name = name; >

Теперь закрытый блок set мы сможем использовать только в данном классе — в его методах, свойствах, конструкторе, но никак не в другом классе:

При использовании модификаторов в свойствах следует учитывать ряд ограничений:

  • Модификатор для блока set или get можно установить, если свойство имеет оба блока (и set, и get)
  • Только один блок set или get может иметь модификатор доступа, но не оба сразу
  • Модификатор доступа блока set или get должен быть более ограничивающим, чем модификатор доступа свойства. Например, если свойство имеет модификатор public, то блок set/get может иметь только модификаторы protected internal, internal, protected, private protected и private

Автоматические свойства

Свойства управляют доступом к полям класса. Однако что, если у нас с десяток и более полей, то определять каждое поле и писать для него однотипное свойство было бы утомительно. Поэтому в .NET были добавлены автоматические свойства. Они имеют сокращенное объявление:

class Person < public string Name < get; set; >public int Age < get; set; >public Person(string name, int age) < Name = name; Age = age; >>

На самом деле тут также создаются поля для свойств, только их создает не программист в коде, а компилятор автоматически генерирует при компиляции.

В чем преимущество автосвойств, если по сути они просто обращаются к автоматически создаваемой переменной, почему бы напрямую не обратиться к переменной без автосвойств? Дело в том, что в любой момент времени при необходимости мы можем развернуть автосвойство в обычное свойство, добавить в него какую-то определенную логику.

Стоит учитывать, что нельзя создать автоматическое свойство только для записи, как в случае со стандартными свойствами.

Автосвойствам можно присвоить значения по умолчанию (инициализация автосвойств):

Person tom = new(); Console.WriteLine(tom.Name); // Tom Console.WriteLine(tom.Age); // 37 class Person < public string Name < get; set; >= «Tom»; public int Age < get; set; >= 37; >

И если мы не укажем для объекта Person значения свойств Name и Age, то будут действовать значения по умолчанию.

Автосвойства также могут иметь модификаторы доступа:

class Person < public string Name < private set; get;>public Person(string name) => Name = name; >

Мы можем убрать блок set и сделать автосвойство доступным только для чтения. В этом случае для хранения значения этого свойства для него неявно будет создаваться поле с модификатором readonly, поэтому следует учитывать, что подобные get-свойства можно установить либо из конструктора класса, как в примере выше, либо при инициализации свойства:

class Person < // через инициализацию свойства public string Name < get; >= «Tom»; // через конструктор public Person(string name) => Name = name; >

Блок init

Начиная с версии C# 9.0 сеттеры в свойствах могут определяться с помощью оператора init (от слова «инициализация» — это есть блок init призван инициализировать свойство).

Для установки значений свойств с init можно использовать только инициализатор, либо конструктор, либо при объявлении указать для него значение. После инициализации значений подобных свойств их значения изменить нельзя — они доступны только для чтения. В этом плане init-свойства сближаются со свойствами для чтения. Разница состоит в том, что init-свойства мы также можем установить в инициализаторе (свойства для чтения установить в инициализаторе нельзя). Например:

Читайте также:
Что за программа hicare в телефоне

Person person = new(); //person.Name = «Bob»; //! Ошибка — после инициализации изменить значение нельзя Console.WriteLine(person.Name); // Undefined public class Person < public string Name < get; init; >= «Undefined»; >

В данном случае класс Person для свойства Name вместо сеттера использует оператор init . В итоге на строке

Person person = new();

предполагается создание объекта с инициализацией всех его свойств. В данном случае свойство Name получит в качестве значения строку «Undefined». Однако поскольку инициализация свойства уже произошла, то на строке

person.Name = «Bob»; // Ошибка

мы получим ошибку.

Как можно установить подобное свойство? Выше продемонстрирован один из способов — установка значения при определении свойства. Второй способ — через конструктор:

Person person = new(«Tom»); Console.WriteLine(person.Name); // Tom public class Person < public Person(string name) =>Name = name; public string Name < get; init; >>

Третий способ — через инициализатор:

Person person = new() < Name = «Bob»>; Console.WriteLine(person.Name); // Bob public class Person < public string Name < get; init; >= «»; >

В принцпе есть еще четверый способ — установка через другое свойство с модификатором init :

В данном случае в init-свойстве Name разворачивается в полное свойство, которое управляет полем для чтения name . Благодаря этому перед установкой значения свойства мы можем произвести некоторую предобработку. Кроме того, в выражении init установливается другое init-свойство — Email, которое для установки значения использует значение свойства Name — из имени получаем значение для электронного адреса.

Причем если если при объявлении свойства указано значение, то в конструкторе мы можем его изменить. Значение, установленное в конструкторе, можно изменить в инициализаторе. Однако дальше процесс инициализации заканчивается. И значение не может быть изменено.

Сокращенная запись свойств

Как и методы, мы можем сокращать определения свойств. Поскольку блоки get и set представляют специальные методы, то как и обычные методы, если они содержат одну инструкцию, то мы их можем сократить с помощью оператора => :

class Person < string name; public string Name < get =>name; set => name = value; > >

Также можно сокращать все свойство в целом:

class Person < string name; // эквивалентно public string Name < get < return name; >> public string Name => name; >

модификатор required

Модификатор required (добавлен в C# 11) указывает, что поле или свойства с этим модификатором обязательно должны быть инициализированы. Например, в следующем примере мы получим ошибку:

Person tom = new Person(); // ошибка — свойства Name и Age не инициализированы public class Person < public required string Name < get; set; >public required int Age < get; set; >>

Здесь свойства Name и Age отчемены как обязательные для инициализации с помощью модификатора required , поэтому необходимо использовать инициализатор для их инициализации:

Person tom = new Person < Name = «Tom», Age = 38 >; // ошибки нет

Причем не важно, устанавливаем эти свойства в конструкторе или инициализируем при определении, все равно надо использовать инициализатор для установки их значений. Например, в следующем примере мы получим ошибку:

Person bob = new Person(«Bob»); // ошибка — свойства Name и Age все равно надо установить в инициализаторе public class Person < public Person(string name) < Name = name; >public required string Name < get; set; >public required int Age < get; set; >= 22; >

Источник: metanit.com

Что такое «init»

Объяснить что такое «раздельная компиляция», что такое «интерфейс класса» и «реализация класса» на примере
Есть класс, содержащий объекты и конструктор. Конструктор объявляется в одном из cpp файлов(их.

Что такое «широкие» и «узкие» С-строки
Гуглила, и не нашла более-менее нормального ответа на вопрос: «Что же такое «широкие» и «узкие».

Что такое «static const» и «enum»?
Я начала изучать ООП . И у меня появился вопрос, что такое «static const» и «enum»? Я.

1813 / 1414 / 484
Регистрация: 29.06.2020
Сообщений: 5,409
Производство лулзов запущено.
Кто первый ?
Кликните здесь для просмотра всего текста

Регистрация: 07.12.2022
Сообщений: 28
Я по-серьезному. Что такое init?
В инете нет ответа.
1813 / 1414 / 484
Регистрация: 29.06.2020
Сообщений: 5,409
Что такое init?
Это кандибобер такой.
Регистрация: 07.12.2022
Сообщений: 28
Что тогда эта ерунда в c++ забыла
16387 / 8899 / 2185
Регистрация: 30.01.2014
Сообщений: 15,402
Hello Wo_rld, вам намекают, что неплохо бы озвучить контекст.
Регистрация: 07.12.2022
Сообщений: 28
За что тут отвечает «init»:
void init(int matrix[M][N]) и тут init(matrix)?
16387 / 8899 / 2185
Регистрация: 30.01.2014
Сообщений: 15,402
За что тут отвечает «init»:
void init(int matrix[M][N]) и тут init(matrix)?

За инициализацию матрицы, видимо.

А вообще, вас за каждую лишнюю строчку кода бьют что ли? Показывайте код, о котором спрашиваете, иначе так и будете получать ответы про «кандибобер».

Эксперт С++

12568 / 10089 / 6071
Регистрация: 18.12.2011
Сообщений: 27,056

Лучший ответ

Сообщение было отмечено Hello Wo_rld как решение

Решение

void init(int matrix[M][N])

Если поставить точку с запятой в конце, то это будет объявление функции init,
параметром которой является матрица из M столбцов и N строк

init(matrix);

вызов этой функции с фактическим параметром matrix
(имена фактического и формального параметра совпали случайно).

7252 / 6201 / 2829
Регистрация: 14.04.2014
Сообщений: 26,785

Ну матрицу заполняет, видимо.
Как ты вообще решил, что та программа тебе подходит, если не понимаешь, что она делает?

Регистрация: 07.12.2022
Сообщений: 28

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
#include #include using namespace std; const int M = 10, N = 8; void init(int matrix[M][N]) { for (int i = 0; i M; i++) { for (size_t j = 0; j N; j++) { matrix[i][j] = rand() % 73 — 41; } } } void print(int matrix[M][N]) { for (int i = 0; i M; i++) { for (int j = 0; j N; j++) { cout <‘ ‘(4)[i][j]; } cout ; } } bool containsZero(int row[N]) { for (int j = 0; j N; j++) { if (row[j] == 0) return true; } return false; } int negativeCount(int matrix[M][N], size_t columnIndex) { int count = 0; for (size_t i = 0; i M; i++) { if (matrix[columnIndex][i] 0) { count ++; } } return count; } int main() { int matrix[M][N]; srand(time(NULL)); init(matrix); print(matrix); cout ; int zeroLines = 0; for (int i = 0; i M; i++) { if (containsZero(matrix[i])) { zeroLines++; } } cout <«Кол-во строк с нулями: » <‘n’; int minNegativeCount = M + 1; int minNegativeIndex = N; for (size_t j = 0; j N; j++) { int count = negativeCount(matrix, j); if (count minNegativeCount) { minNegativeCount = count; minNegativeIndex = j; } } if (minNegativeIndex N) { cout <«Номер столбца с наименьшим кол-вом отрицательных элементов: » <‘n’; } else { cout <«Отрицательных элементов в матрице нетn»; } return 0; }

Источник: www.cyberforum.ru

Программа init

Самым первым процессом является программа init. И от того, каким образом она сконфигурирована, зависит дальнейшая загрузка системы.

Ядро Linux при старте обязательно монтирует корневую файловую систему (обычно в режиме только для чтения). Поэтому при запуске init может быть запущен (для этого необходимо получить доступ к файлу программы) и может прочитать свой конфигурационный файл /etc/inittab.

Процесс запуска init каждый, кто знаком с языком программирования C, может посмотреть в исходных кодах ядра, в файле init/main.c, для остальных (а также просто ленивых) скажу, что:

когда наступает время породить первый процесс, то первым делом ядро пытается запустить программу, указанную опцией rdinit=;

если таковой опции ядру передано не было, то будет запущен /init;
если ничего не вышло с /init, то ядро пытается запустить программу, указанную опцией init=;
если это не получилось, то ядро пытается запустить /sbin/init;
если возникли проблемы с /sbin/init, то ядро пытается запустить /etc/init;
если не удалось запустить /etc/init, то ядро пытается запустить /bin/init;
если невозможно запустить /bin/init, то ядро пытается запустить /bin/sh;
ну а если даже и /bin/sh подвёл, то ядро паникует с сообщением

No init found. Try passing init= option to kernel.

Никогда не выносите в отдельный раздел директории /bin, /sbin, /etc, /dev. Файлы находящиеся в них могут потребоваться при старте системы. Ярким примером являются программа init и ее конфигурационный файл /etc/inittab.

Уровни выполнения

В Linux существует такое понятие как уровень выполнения (run level). Уровень выполнения обозначается числами от 0 до 6.

Система в определенный момент времени находится на соответствующем уровне выполнения. Вы, как администратор системы можете переводить ее с одного уровня выполнения на другой. Это делается при помощи программы init (или telinit). Для этого программе в качестве аргумента передается число соответствующее уровню выполнения. Например, что бы перевести систему на 3-й уровень выполнения, необходимо запустить init следующим образом:

Читайте также:
Программу апдейтер что это

init 3

В различных дистрибутивах Linux уровни выполнения используются для различных целей.

Современная версия программы init может использовать десять уровней выполнения, но обычно используются только семь.

0 — выполняются действия по выключению системы.

1 — однопользовательский режим (single user mode). Предназначен для различных административных действий по восстановлению системы. По своему смыслу аналогичен Safe Mode Windows, но полностью его не повторяет. На этом уровне выполнения система полностью сконфигурирована, но не запущен ни один сервис, а из пользователей может работать только один root.

2 — не используется, но сконфигурирован как уровень выполнения 3. В RedHat и SuSE Linux, сконфигурирован, как уровень выполнения 3, но без поддержки сетевых файловых систем. В Debian используется как многопользовательский режим.

3 — многопользовательский режим (multiuser mode). Нормальный режим работы сервера.

4 — В Slackware Linux используется для графического входа в систему. В RedHat и SuSE Linux не сконфигурирован.

5 — В RedHat и SuSE Linux используется для графического входа в систему. В Slackware Linux не сконфигурирован.

6 — выполняются действия по перезагрузке системы.

Суперпользователь может остановить систему, переведя её на нулевой уровень:

init 0

Или перегрузить систему:

init 6

Формат файла /etc/inittab

Конфигурационный файл программы init — это текстовый файл. Символ комментария — #. Файл состоит из строк следующего формата:

id:run_level:action:process

id — идентификатор, один или два символа. Поле должно быть уникальным. Никак не влияет на работу современной версии программы init.

run_level — список уровней выполнения, на которых будет выполняться программа. Поле может быть пустым.

action — определяет особенности выполнения программы. В этом поле можно писать только заранее определенные слова.

process — программа, которая будет выполняться.

Init рассматривает строки в том порядке, в котором они написаны в файле. Предположим, что мы хотим перевести систему на третий уровень выполнения и запускаем init следующим образом:

init 3

Программа начнет выполнять только те строки, в поле run_level которых будет присутствовать цифра 3. То есть, будут запускаться программы, описанные в поле process, но с некоторыми оговорками, определяемые полем action.

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

Давайте рассмотрим конфигурационный файл inittab на примере дистрибутива Slackware Linux. Ниже показано содержимое этого файла, за исключением комментариев и пустых строк.

id:3:initdefault: si:S:sysinit:/etc/rc.d/rc.S su:1S:wait:/etc/rc.d/rc.K rc:2345:wait:/etc/rc.d/rc.M ca::ctrlaltdel:/sbin/shutdown -t5 -r now l0:0:wait:/etc/rc.d/rc.0 l6:6:wait:/etc/rc.d/rc.6 pf::powerfail:/sbin/genpowerfail start pg::powerokwait:/sbin/genpowerfail stop c1:1235:respawn:/sbin/agetty 38400 tty1 linux c2:1235:respawn:/sbin/agetty 38400 tty2 linux c3:1235:respawn:/sbin/agetty 38400 tty3 linux c4:1235:respawn:/sbin/agetty 38400 tty4 linux c5:1235:respawn:/sbin/agetty 38400 tty5 linux c6:12345:respawn:/sbin/agetty 38400 tty6 linux x1:4:wait:/etc/rc.d/rc.4

При старте системы ядро запускает программу init без указания уровня выполнения. То есть, просто

init

Программе каким то образом необходимо узнать, какие строки в этом случае выполнять. Какой уровень выполнения использовать? Для указания уровня выполнения используется строка

id:3:initdefault:

Это первое исключение из общего правила. Как видите поле process пустое. В поле action написано ключевое слово initdefault, которое означает, что в поле run_level написан уровень выполнения используемый по умолчанию.

Дальше мы будем рассматривать файл с учетом того, что система стартует на третьем уровне выполнения.

В следующей строке нас ждет сразу два исключения из общего правила!

si:S:sysinit:/etc/rc.d/rc.S

Во первых, в поле run_level стоит буква S, да и action sysinit, не просто так тут написана.

Начнем с буквы S. Когда ядру при загрузке передается параметр single, ядро запускает программу init таким образом, что она перестает реагировать на все строки, кроме тех, в поле run_level которых стоит буква S. Обычно дистрибутивы сконфигурированы таким образом, что бы в этом случае система запускалась на уровне выполнения 1 (single user mode).

Действие sysinit означает, что программа, описанная в поле process будет выполняться только при старте системы, и init будет ожидать ее завершения, прежде чем начнет выполнять следующие строки. Таким образом, программа /etc/rc.d/rc.S будет выполняться только при старте системы. При переходе с одного уровня выполнения на другой она запускаться не будет.

su:1S:wait:/etc/rc.d/rc.K

Строка на третьем уровне выполнения работать не будет, мы ее пропустим.

rc:2345:wait:/etc/rc.d/rc.M

В поле run_level присутствует цифра три, поэтому программа /etc/rc.d/rc.M будет запущена. Действие wait означает, что init будет ожидать завершение выполнения программы, прежде, чем начнет выполнять следующие строки из файла inittab. Таким образом, второй при старте системы будет запущена программа rc.M.

ca::ctrlaltdel:/sbin/shutdown -t5 -r now

В поле run_level этой строки нет ни одной цифры, значит она не будет выполняться при старте системы. Как то странно при старте сразу запускать программу shutdown. Но в поле действие присутствует интересный параметр: ctrlaltdel. Он заставляет init следить за нажатием комбинации клавиш Ctrl(левый)+Alt(левый)+Del.

И если кто то их нажмет, выполнит программу, указанную в поле process.

Обратите внимание на то, что не имеет значения, залогинился пользователь в систему или нет. Любой проходящий мимо человек может нажать эту комбинацию клавиш и система будет перезагружена.

l0:0:wait:/etc/rc.d/rc.0 l6:6:wait:/etc/rc.d/rc.6

Эти две строки никакого отношения к третьему уровню выполнения не имеют, поэтому мы их пропускаем. никакого

pf::powerfail:/sbin/genpowerfail start pg::powerokwait:/sbin/genpowerfail stop

Поле run_level в этих строках пустое, поэтому при старте системы они работать не будут. Но, init их запомнит. Для того, что бы эти строки заработали, необходимо, что бы у вас был интеллектуальный UPS, подключенный к вашей машине. А так же запущена программа, которая понимает команды UPS (обычно используют программу genpowerd).

Если питание пропадет, то UPS сообщит об этом программе, а та в свою очередь передаст информацию init, который обработает действие powerfail. Если питание восстановится, будет обработано действие powerokwait.

Программа genpowerfail — это обыкновенный скрипт. Если его запустить с параметром start, то будет запущена программа shutdown. В зависимости от состояния UPS, процедура остановки системы будет произведена сразу или с задержкой на одну или две минуты. Если скрипт запустить с параметром stop, то процедура остановки системы будет отменена (shutdown -c).

c1:1235:respawn:/sbin/agetty 38400 tty1 linux c2:1235:respawn:/sbin/agetty 38400 tty2 linux c3:1235:respawn:/sbin/agetty 38400 tty3 linux c4:1235:respawn:/sbin/agetty 38400 tty4 linux c5:1235:respawn:/sbin/agetty 38400 tty5 linux c6:12345:respawn:/sbin/agetty 38400 tty6 linux

После выполнения программ rc.S и rc.M, init запускает программу agetty. В других дистрибутивах может быть другая версия программы. Например, в SuSE Linux используется mingetty.

Задача программы — инициализировать консоль на последовательном устройстве. В нашем случае, инициализируются консоли на виртуальных терминалах с 1-го по 6-й.

Обратите внимание на то, что в Slackware Liniux, на 4-м уровне выполнения (графический вход в систему) консоль инициализируется только на 6-м виртуальном терминале.

Согласно действия respawn, init запускает программу и не ожидая ее завершения выполняет следующие строки. Но он не забывает о запущенных программах, он за ними следит. Если программа завершит свою работу — init запускает ее снова. Именно поэтому, после выхода из системы на экране терминала появляется приглашение входа в систему.

x1:4:wait:/etc/rc.d/rc.4

Эта строка будет выполняться только на 4-м уровне выполнения.

Действия

В таблице приведены некоторые ключевые слова, которые можно использовать в поле действие.

initdefault Определяет уровень выполнения по умолчанию во время загрузки системы.
sysinit Программа будет выполняться при запуске системы самой первой. init будет ожидать её завершение, прежде чем начнет выполнение следующих в списке программ.
wait Программа запускается один раз. init будет ожидать ее завершение, прежде чем начнет выполнение следующих в списке программы.
once Программа запускается один раз. init не ждет её завершения.
ctrlaltdel Определяет программу, которая будет запущена при нажатии на клавиши «Ctrl+Alt+Del».
powerfail Определяет программу, которая будет запущена при получении процессом init сигнала сбоя питания.
powerokwait Определяет программу, которая будет запущена при получении процессом init сигнала восстановления питания.
respawn Процесс будет запущен. init не будет ожидать окончания процесса и начнет обрабатывать следующие в списке строки. Если процесс завершит свою работу – init запустит его снова.

Из конфигурационного файла можно сделать вывод, что в Slackware Linux на уровне выполнения 3, init запускает следующие программы:

/sbin/agetty для каждой виртуальной консоли.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website. OK More information about cookies

Источник: rtfm.wiki

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru