[RUBY] Je vois, je vais lire le processus UNIX

――Tout dans Ruby reflète les appels système, la culture et les idées Unix. ―― En utilisant Ruby, vous pouvez laisser le bas niveau au langage et apprendre l'idée d'Unix lui-même.

Chapitre 1 Introduction

Chapitre 2 Guide de ce livre

―― L'idée de la programmation Unix et de sa technologie sera utile pour les 40 prochaines années.

--Appel système

  1. Userland
  1. Noyau --Une couche intermédiaire pour contrôler le matériel, située en haut du matériel de l'ordinateur.

--man page

  1. Lorsque vous écrivez un programme en C et que vous voulez savoir comment utiliser les appels système.
  2. Lorsque vous souhaitez comprendre le but d'un appel système.

--section de la page de manuel

  1. Commandes utilisateur que tout le monde peut exécuter (commandes shell)
  2. Appel système (fonction fournie par le noyau)
  3. Sous-section (fonction de bibliothèque C)
  4. Device (fichier spécial dans le répertoire / dev)

--Processus: atome Unix --Tout le code est exécuté sur le processus.

Chapitre 3 Le processus a un ID

--Référence mutuelle Commande --ps (1) --Le pid renvoie les informations vues par le noyau.

--Commandes pouvant être référencées avec les informations fournies par le système d'exploitation - top(1) --Affichez le processus en cours en temps réel. - lsof(8)

Chapitre 3 Process a des parents

--Processus parent

--Exemple --Lorsque vous démarrez "Terminal.app" sur Mac OS X, vous serez invité à bash.

Chapitre 5 Les processus ont des descripteurs de fichier

--Tout est un fichier --Une philosophie Unix.

  1. Entrée standard (STDIN)
  2. Sortie standard (STDOUT)
  3. Sortie d'erreur standard (STDERR)

Chapitre 6 Les processus ont des limitations de ressources

―― Combien de descripteurs de fichier un processus peut-il avoir?

Chapitre 7 Le processus a un environnement

--ENV implémente partiellement les API Enumerable et Hash, mais n'a pas exactement les mêmes fonctionnalités que Hash.

$ RAILS_ENV=production rails server
$ EDITOR=mate bundle open actionpack
$ QUEUE=default rake resque:work

Chapitre 8 Les processus ont des arguments

$ cat argv.rb
p ARGV
$ ruby argv.rb foo bar -va
["foo", "bar", "-va"]

Chapitre 9 Les processus ont des noms

--Deux mécanismes pour transmettre des informations au niveau du processus.

  1. Nom du processus
  2. Code de fin

Chapitre 10 Le processus a un code de fin

--Valeur de code de fin

--Fin du code 0

--Comment mettre fin au processus 1. exit 2. exit! 3. abort 4. raise

Chapitre 11 Les processus peuvent créer des processus enfants

--Génération de processus

méthode --fork

#Les clauses if et else de l'instruction if sont exécutées
#Du côté du processus parent, le pid du processus enfant créé est retourné, et du côté du processus enfant, fork renvoie nil.
if fork
  puts "entered the if block" 
else
  puts "entered the else block" 
end
=> entered the if block
entered the else block

--Utiliser des blocs

fork do
  #Décrivez ici le processus à exécuter dans le processus enfant
end

#Décrivez ici le processus à exécuter par le processus parent

Chapitre 12 Processus orphelin

Chapitre 13 Le processus est doux

--Copie en écriture (CoW, copie en écriture)

--CoW est très pratique et rapide pour économiser des ressources lors de la création de processus enfants avec fork (2).

--Pour que CoW fonctionne correctement, l'implémentation Ruby doit être écrite de manière à ne pas casser cette fonctionnalité fournie par le noyau.

Chapitre 14 Le processus peut attendre

--Fire et oublier --Lorsque vous souhaitez que le processus enfant se déroule de manière asynchrone et que le processus parent souhaite procéder indépendamment.

message = 'Good Morning'
recipient = '[email protected]'

fork do
  #Lancer un processus enfant et envoyer des données au collecteur de statistiques
  #Le processus parent continue le processus d'envoi de message réel.
  #
  #En tant que processus parent, je ne veux pas que ce travail ralentisse
  #Je m'en fiche si la transmission au collecteur de statistiques échoue pour une raison quelconque.
  StatsCollector.record message, recipient
end

#Envoyer un message à la destination réelle

--Protection de l'enfance

Changer avant:

fork do
  5.times do
    sleep 1
    puts "I'm an orphan!"
  end
end

abort "Parent process died..."

Après le changement:

fork do
  5.times do
    sleep 1
    puts "I am an orphan!"
  end
end

Process.wait
abort "Parent process died..."
I am an orphan!
I am an orphan!
I am an orphan!
I am an orphan!
I am an orphan!
Parent process died...

--L'état de fin est utilisé comme moyen de communication entre les processus par le code de fin.

Exemple de communication interprocessus sans système de fichiers ni réseau:

#Spawn 5 processus enfants
5.times do
  fork do
    #Générez une valeur aléatoire pour chaque processus enfant.
    #S'il est pair, il renvoie 111, et s'il est impair, il renvoie 112 comme code de fin.
    if rand(5)
      exit 111
    else
      exit 112
    end
  end
end

5.times do
  #Attendez que le processus enfant généré se termine.
  pid, status = Process.wait2

  #Si le code de fin est 111
  #Vous pouvez voir que les valeurs générées côté processus enfant sont paires.
  if status.exitstatus == 111
    puts "#{pid} encountered an even number!"
  else
    puts "#{pid} encountered an odd number!"
  end
end
favourite = fork do
  exit 77
end

middle_child = fork do
  abort "I want to be waited on!"
end

pid, status = Process.waitpid2 favourite
puts status.exitstatus

--Process.wait et Process.waitpid pointent tous deux vers la même fonction.

Chapitre 15 Processus des zombies

--Détachement du processus enfant

Exemple:

message = 'Goog Morning'
recipient = '[email protected]'

pid = fork do
  #Créer un processus enfant et envoyer les données au collecteur de statistiques
  #Le processus parent continue le processus d'envoi de message réel.
  # 
  #En tant que processus parent, je ne veux pas que ce travail ralentisse
  #Je m'en fiche si la transmission au collecteur de statistiques échoue pour une raison quelconque.
  StatsCollector.record message, recipient
end

#Assurez-vous que le processus enfant qui collecte les statistiques ne devient pas un zombie.
Process.detach(pid)

Chapitre 16 Les processus peuvent recevoir des signaux

--Process.wait est un appel bloquant --Process.wait permet au processus parent de gérer le processus enfant, mais le processus parent ne peut pas continuer le traitement tant que le processus enfant n'est pas terminé.

--Exemple pour compléter SIGCHLD

child_processes = 3
dead_processes = 0
#Spawn 3 processus enfants
child_processes.times do
  fork do
    #Dormez pendant 3 secondes chacun
    sleep 3
  end
end

#Après cela, le processus parent est occupé par des calculs lourds,
#Je souhaite détecter la fin d'un processus enfant.

#Donc,:Complétez le signal CHLD. En faisant cela
#Vous pouvez recevoir des notifications du noyau lorsqu'un processus enfant se termine.
trap(:CHLD) do
  #Traiter les informations du processus enfant terminé.Si vous l'obtenez avec attente,
  #Vous pouvez voir lequel des processus enfants générés s'est terminé.
  puts Process.wait
  dead_processes += 1
  #Terminez explicitement le processus parent lorsque tous les processus enfants sont terminés.
  exit if dead_processes == child_processes
end

#Traitement de calcul lourd
loop do
  (Math.sqrt(rand(44)) ** 8).floor
  sleep 1
end

--Parallèle avec SIGCHLD

--Gérer correctement CHLD

--Deuxième argument de Process.wait --Correspondance à la situation où vous pouvez recevoir plusieurs signaux CHLD pendant le traitement du signal.

Process.wait(-1, Process::WNOHANG)

--Guide des signaux

  1. Ignorez le signal
  2. Effectuer un traitement spécifique
  3. Effectuez le processus par défaut

--L'utilisation originale des signaux était de spécifier comment tuer un processus.

—— Les signaux sont un excellent outil et fonctionnent très bien dans certaines situations. ――Mais gardez à l'esprit que compléter les signaux revient à utiliser des variables globales.

--Si vous connaissez le pid, vous pouvez communiquer avec n'importe quel processus du système par signal.

――Parlant des signaux dans le monde réel, la plupart d'entre eux sont utilisés par des processus qui continuent à fonctionner pendant une longue période, tels que les serveurs et les démons.

Chapitre 17 Les processus peuvent communiquer

Chapitre 18 Processus démoniaque

Chapitre 19 Processus du terminal

Conclusion du chapitre 20

Recommended Posts

Je vois, je vais lire le processus UNIX
J'ai lu l'article de SHAP
[Unix] Qu'est-ce que le processus zombie / processus orphelin?
J'ai lu l'implémentation de range (Objects / rangeobject.c)
J'ai lu et implémenté les variantes de UKR
[Python] Je vais télécharger FTP sur le serveur FTP.
Je veux voir le nom de fichier de DataLoader
Pour la première fois, j'ai découvert Unix (Linux).
Essayez d'installer Arch Linux pour le moment.
J'ai lu la référence Chainer (mise à jour de temps en temps)
Lire la documentation OpenCV
J'ai compté les grains
Cela ... ne peut pas voir le processus que vous exécutez? La raison pour
Je souhaite utiliser uniquement le traitement de normalisation SudachiPy