偶然之下,发现这种方法产生的图像看起来非常像股票走势图,感觉很有趣,分享出来,也许有所启发。
一个循环队列,大小固定。两个线程,一个put线程,一个get线程,put线程休眠一段时间后,向队列放入一个数据。get线程休眠一段时间后取一个数据。在完成取(放)动作后,检查下自己的休眠时间是否大于对方的休眠时间,如果大于,则更新一次双方的休眠时间。更新时间就是取两个随机数赋予两个线程的休眠时间。
图形X轴是时间,Y轴是队列内数据的数量。
个人强行解释,get相当于空头,put相当于多头。当认为形势对自己有利时,则不采取动作。当认为形势对自己不利时,则采取行动。但是这个行动有不确定性,不一定就是对自己有利。
模拟图如下:
#coding=gbk
import random as rnd
import threading
import time
import matplotlib.pyplot as plt
class SqQueue(object):
def __init__(self, maxsize):
self.queue = [None] * maxsize
self.maxsize = maxsize
self.front = 0
self.rear = 0
#返回当前队列的长度
def QueueLength(self):
return (self.rear - self.front + self.maxsize) % self.maxsize
# 如果队列未满,则在队尾插入元素,时间复杂度O(1)
def EnQueue(self, data):
if (self.rear + 1) % self.maxsize == self.front:
return -1
else:
self.queue[self.rear] = data
# self.queue.insert(self.rear,data)
self.rear = (self.rear + 1) % self.maxsize
return 0
# 如果队列不为空,则删除队头的元素,时间复杂度O(1)
def DeQueue(self):
if self.rear == self.front:
return -1
else:
data = self.queue[self.front]
self.queue[self.front] = None
self.front = (self.front + 1) % self.maxsize
return 0
# 输出队列中的元素
def ShowQueue(self):
for i in range(self.maxsize):
print(self.queue[i],end=',')
print(' ')
q = SqQueue(100)
put_time = rnd.randint(100,3000)
get_time = rnd.randint(100,3000)
def update_time():
global put_time
global get_time
put_time = rnd.randint(100,3000)
get_time = rnd.randint(100,3000)
def put_thread():
while True :
if q.EnQueue(22) == 0:
print("put", q.QueueLength())
if put_time >= get_time:
update_time()
print("put update time",put_time,get_time)
time.sleep(put_time/1000)
def get_thread():
while True :
if q.DeQueue() == 0:
print("get",q.QueueLength())
if put_time <= get_time:
update_time()
print("get update time",put_time,get_time)
time.sleep(get_time/1000)
def show_qlen():
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
obsX = []
obsY = []
i = 1
line = None
while True:
# 往列表插入展示的点的坐标
obsX.append(i)
# Y轴,队列长度
obsY.append(q.QueueLength())
# 如果图还没有画,则创建一个画图
if line is None:
# -代表用横线画,g代表线的颜色是绿色,.代表,画图的关键点,用点代替。也可以用*,代表关键点为五角星
line = ax.plot(obsX, obsY, '-g', marker='.')[0]
# 这里插入需要画图的参数,由于图线,是由很多个点组成的,所以这里需要的是一个列表
line.set_xdata(obsX)
line.set_ydata(obsY)
'''
# 当X轴跑了100次的时候,则让X坐标的原点动起来
if len(obsX) < 100:
ax.set_xlim([min(obsX), max(obsX) + 30])
else:
ax.set_xlim([obsX[-80], max(obsX) * 1.2])
'''
# Y轴加一个10,防止顶到天花板
#ax.set_ylim([min(obsY), max(obsY) + 10])
ax.set_ylim(0, 110)
ax.set_xlim([min(obsX), max(obsX) + 30])
# 这个就是表的刷新时间了,以秒为单位
plt.pause(1)
# 画完一次了,i的数据加1,让X轴可以一直往前走。
i += 1
if __name__ == "__main__":
pt = threading.Thread(target=put_thread)
gt = threading.Thread(target=get_thread)
pt.start()
gt.start()
show_qlen()