Cucco’s Compute Hack

コンピュータ関係の記事を書いていきます。

時刻ちょうどに実行する その2

マルチプロセス版の時刻ちょうどに実行する
2秒ごとと5秒ごとに実行する。ただし開始は0秒から。

import multiprocessing
import datetime
import time

class Worker(multiprocessing.Process):
	def __init__(self,queue,interval=5):
		self.interval=interval
		self.q=q
		
		self.time_now=datetime.datetime.utcnow()
		self.time_offset=datetime.timedelta(seconds=interval) #繰り返しの間隔(秒)
		
		#秒を0にする。
		self.time_next=datetime.datetime(self.time_now.year, self.time_now.month, self.time_now.day, self.time_now.hour, self.time_now.minute, second=0, microsecond=0, tzinfo=None)
		
		while self.time_next < self.time_now:
			self.time_next=self.time_next+self.time_offset
		
		#super(Worker, self).__init__()
		
	def timedelta2sec(self,t):
		return t.days * 3600 * 24 + t.seconds + t.microseconds / 1000000
		
	def run(self):
		
		self.time_now = datetime.datetime.utcnow()
		while self.time_next < self.time_now:
			self.time_next=self.time_next+self.time_offset
		time.sleep(self.timedelta2sec(self.time_next-self.time_now))
			
		while self.q.empty()==True:	#qに何か入ってくれば終了する。
			#今の時間を表示
			self.time_now = datetime.datetime.utcnow()
			print(self.name,self.time_now)
			
			self.time_next = self.time_next + self.time_offset
			self.time_now = datetime.datetime.utcnow()
			
			while self.time_next < self.time_now:
				self.time_next=self.time_next+self.time_offset
			
			time.sleep(self.timedelta2sec(self.time_next-self.time_now))
		return

if __name__ == '__main__':

	q=multiprocessing.SimpleQueue() #終了フラグを入れるために使う
	
	x=Worker(q,interval=2)
	y=Worker(q,interval=5)

	x.start()
	y.start()
	
	time.sleep(20)
	
	print("stop process")
	q.put("STOP")
	
	x.join()
	y.join()
	
	print("end")

実行結果

>C:\Python36\python.exe C:\multiProcessTest.py
Worker-1 2018-03-15 11:36:48.010984
Worker-1 2018-03-15 11:36:50.001188
Worker-2 2018-03-15 11:36:50.001188
Worker-1 2018-03-15 11:36:52.002991
Worker-1 2018-03-15 11:36:54.006795
Worker-2 2018-03-15 11:36:55.006197
Worker-1 2018-03-15 11:36:56.006599
Worker-1 2018-03-15 11:36:58.007403
Worker-2 2018-03-15 11:37:00.009206
Worker-1 2018-03-15 11:37:00.009206
Worker-1 2018-03-15 11:37:02.009010
Worker-1 2018-03-15 11:37:04.007215
Worker-2 2018-03-15 11:37:05.006616
Worker-1 2018-03-15 11:37:06.002419
stop process
end

スーパークラスのコンストラクタを忘れているとこんなエラーになる。

    assert self._popen is None, 'cannot start a process twice'
AttributeError: 'Worker' object has no attribute '_popen'