Last active
May 8, 2017 18:16
-
-
Save sxslex/499b1572378e5663e867ca3885f850b5 to your computer and use it in GitHub Desktop.
Implementa semaphoro para controle de blocos atômicos em arquivo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
"""Implements semaphoro to control atomic blocks on file.""" | |
# by [email protected] | |
import os | |
import sys | |
import uuid | |
import time | |
import signal | |
class Semaphone(object): | |
"""Implements semaphoro to control atomic blocks on file.""" | |
def __init__(self, lockfile): | |
self.lockfile = lockfile | |
self._exit = False | |
self._last = None | |
def signal_handler(signal, frame): | |
self._exit = True | |
self.release() | |
sys.exit(0) | |
signal.signal(signal.SIGINT or signal.SIGTERM, signal_handler) | |
def _ismy(self, myhash): | |
try: | |
return open( | |
self.lockfile, 'r').read().split(None)[0] == myhash | |
except: | |
return False | |
def acquire(self): | |
myhash = uuid.uuid4().hex | |
while True: | |
while os.path.exists(self.lockfile): | |
time.sleep(0.05) | |
if not self._exit: | |
open(self.lockfile, 'a+').write(myhash + '\n') | |
if self._ismy(myhash): | |
self._last = myhash | |
return True | |
time.sleep(0.05) | |
def release(self): | |
if self._ismy(self._last): | |
os.unlink(self.lockfile) | |
time.sleep(0.1) | |
return True | |
def __enter__(self): | |
self.acquire() | |
return self | |
def __exit__(self, exc_type, exc_value, traceback): | |
self.release() | |
return True if exc_type is None else False | |
if __name__ == '__main__': | |
from threading import Thread | |
import random | |
semaphore = Semaphone('.teste_semaphore') | |
def task(i): | |
while True: | |
with semaphore: | |
print('BEGIN TASK: {}'.format(i)) | |
time.sleep(random.randint(1, 3)) | |
print('END TASK..: {}'.format(i)) | |
for i in range(5): | |
t = Thread(target=task, args=(i,)).start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment