J'ai essayé de créer un mécanisme de contrôle exclusif avec Go

Aperçu

C'est mon premier et mon deuxième poste d'ingénieur. J'ai eu l'occasion d'écrire un mécanisme de contrôle exclusif en Go, je vais donc l'enregistrer. Cette fois, nous allons créer un mécanisme de contrôle exclusif en utilisant deux méthodes.

Divers outils

scénario

Cette fois, en utilisant une certaine table comme ressource partagée, lorsque le traitement est effectué sur la table à partir de plusieurs processus, un mécanisme est créé pour empêcher les processus suivants de faire fonctionner la table jusqu'à ce que le processus précédent soit terminé. Je vais continuer.

Tout d'abord, essayez de mettre à jour la table en même temps en utilisant le goroutine sans effectuer de contrôle exclusif. (sync.WaitGroup est pour attendre la goroutine principale. Pour plus d'informations ici.)

var w sync.WaitGroup

func main() {
	w.Add(2)
	go update()
	go update()
	w.Wait()
}

func update() {
	defer w.Done()
	for i := 0; i <= 10; i += 5 {
		fmt.Println("tbl update:", i*10, "%")
		time.Sleep(time.Second)
	}
}

// tbl update: 0 %
// tbl update: 0 %
// tbl update: 50 %
// tbl update: 50 %
// tbl update: 100 %
// tbl update: 100 %

Vous pouvez voir que les deux processus mettent à jour la table en même temps. Cette fois, nous allons créer un mécanisme pour obtenir la sortie suivante afin que la mise à jour suivante soit effectuée une fois la mise à jour précédente terminée.

// tbl update: 0 %
// tbl update: 50 %
// tbl update: 100 %
// tbl update: 0 %
// tbl update: 50 %
// tbl update: 100 %

Modèle utilisant sync.Mutex

Tout d'abord, depuis sync.Mutex.

//La fonction principale est la même que ci-dessus

var m sync.Mutex

func update() {
	defer w.Done()
	defer m.Unlock()
	m.Lock()
	for i := 0; i <= 10; i += 5 {
		fmt.Println("tbl update:", i*10, "%")
		time.Sleep(time.Second)
	}
}
// tbl update: 0 %
// tbl update: 50 %
// tbl update: 100 %
// tbl update: 0 %
// tbl update: 50 %
// tbl update: 100 %

Déclarez «UnLock ()» et «Lock ()» au début de «update ()». Les goroutines suivantes ne peuvent pas appliquer Lock () jusqu'à ce que les goroutines précédentes UnLock () (jusqu'à ce que le traitement de la fonction soit terminé), et par conséquent, elles vont attendre que le traitement des goroutines précédentes se termine. Vous pouvez voir que la sortie est comme vous le souhaitiez.

sync.Mutex est très simple et direct, mais il ne fait qu'un seul processus. C'est un peu différent de ce scénario, mais il semble difficile de créer un mécanisme tel que "pour réduire la charge sur le serveur, empêcher plus de 1000 processus de s'exécuter en même temps".

Modèle utilisant semapho

Puisque c'est la première fois que j'utilise un semapho, j'écrirai sur ce qu'est un semafo.

Qu'est-ce que Semafo?

Semafo est l'un des mécanismes de contrôle exclusifs et modélise l'exploitation des lignes ferroviaires. (Sémaphore signifie signal en japonais) Il a été créé pour contrôler la ressource partagée des lignes afin qu'elles ne soient pas utilisées en même temps. Un semapho se compose de trois variables de semapho, une opération P et une opération V.

--Variable Mapho --Nombre de processus pouvant accéder aux ressources partagées ――Ce ne sera pas négatif --Une variable sémapho qui ne prend que 0 ou 1 est appelée un ** semapho binaire (sémapho binaire) **, et une variable qui prend 0 à N est appelée un ** semapho général **. --P opération --Décrémenter la variable semapho --Un processus sécurise les ressources partagées -V opération --Incrémenter la variable semapho --Un processus libère des ressources partagées

Ce scénario est un semapho binaire, et il semble qu'il soit nécessaire d'effectuer l'opération P au début de update () et l'opération V à la fin.

la mise en oeuvre

golang.org/x/syncを使って実装します。


const semaphoreCnt = 1

var s *semaphore.Weighted = semaphore.NewWeighted(semaphoreCnt)

func update() {
	defer w.Done()
	defer s.Release(1)           //Opération V Augmentez la variable semapho de 1.
	s.Acquire(context.TODO(), 1) //Opération P: Diminuez la variable semapho de 1.
	for i := 0; i <= 10; i += 5 {
		fmt.Println("tbl update:", i*10, "%")
		time.Sleep(time.Second)
	}
}
// tbl update: 0 %
// tbl update: 50 %
// tbl update: 100 %
// tbl update: 0 %
// tbl update: 50 %
// tbl update: 100 %

golang.org/x/syncAcquire()がP操作に,Release()がV操作にあたります。 Le contrôle exclusif est réalisé en définissant une variable semapho avec semaphore.Weighted et en l'augmentant ou en la diminuant en utilisant Acquire () etRelease ().

また、golang.org/x/syncでは、Acquire(),Release()でセマフォ変数をいくつ増減させるかを調節することが出来ます。(今回は2値セマフォのため、それぞれ1増減となっています。) Cela vous permet de définir les poids de traitement pour chaque processus.

golang.org/x/syncを使うことでsync.Mutexと比べ、より複雑な排他制御の仕組みを作ることができます。

référence

Recommended Posts

J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
J'ai créé une API de recherche de château avec Elasticsearch + Sudachi + Go + echo
J'ai essayé de faire quelque chose comme un chatbot avec le modèle Seq2Seq de TensorFlow
J'ai créé une API Web
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer une expression régulière de "montant" en utilisant Python
J'ai essayé de créer une expression régulière de "temps" en utilisant Python
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de créer une liste de nombres premiers avec python
J'ai essayé de créer une expression régulière de "date" en utilisant Python
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
Je veux faire un jeu avec Python
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
J'ai essayé de faire un signal avec Raspeye 4 (édition Python)
J'ai essayé de créer un service de raccourcissement d'url sans serveur avec AWS CDK
J'ai essayé de faire un "putain de gros convertisseur de littérature"
J'ai essayé de faire un processus périodique avec CentOS7, Selenium, Python et Chrome
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
Quand j'ai essayé de créer un VPC avec AWS CDK mais que je n'ai pas pu le faire
[Analyse des brevets] J'ai essayé de créer une carte des brevets avec Python sans dépenser d'argent
[Go + Gin] J'ai essayé de créer un environnement Docker
J'ai essayé de créer une application OCR avec PySimpleGUI
J'ai essayé de créer une API de reconnaissance d'image simple avec Fast API et Tensorflow
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
J'ai essayé de faire une simulation de séparation de source sonore en temps réel avec l'apprentissage automatique Python
[Python] J'ai essayé de créer automatiquement un rapport quotidien de YWT avec la messagerie Outlook
J'ai essayé de faire de l'art créatif avec l'IA! J'ai programmé une nouveauté! (Article: Réseau Adversaire Créatif)
J'ai essayé d'implémenter une ligne moyenne mobile de volume avec Quantx
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé de créer diverses "données factices" avec Python faker
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
J'ai essayé de créer automatiquement un rapport avec la chaîne de Markov
Je veux créer un éditeur de blog avec l'administrateur de django
J'ai essayé de résoudre le problème d'optimisation des combinaisons avec Qiskit
Je veux faire une macro de clic avec pyautogui (Outlook)
J'ai essayé de commencer avec Hy ・ Définir une classe
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai essayé de trier une colonne FizzBuzz aléatoire avec un tri à bulles.
J'ai fait un chronomètre en utilisant tkinter avec python
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai essayé de simuler la probabilité d'un jeu de bingo avec Python
J'ai essayé d'écrire dans un modèle de langage profondément appris
J'ai créé un éditeur de texte simple en utilisant PyQt
J'ai créé une fonction pour récupérer les données de la colonne de base de données par colonne en utilisant sql avec sqlite3 de python [sqlite3, sql, pandas]
[1 hour challenge] J'ai essayé de créer un site de bonne aventure qui soit trop adapté à Python