注:以下代码为原创,若发现bug,万望指出,若有问题,欢迎交流,转载请指明出处。若能有助于一二访客,幸甚。
欢迎关注babyos 的成长历程和宝贝计划:https://github.com/guzhoudiaoke/babyos/wiki
前面已经实现了一个简易的图形库,那么实现一个简单的图形界面是理所当然的事。
babyos走的是好玩、可爱、漂亮的路线,怎么好玩怎么来,怎么漂亮怎么来,所以这个图形界面还是着实费了一番功夫的,属于高级山寨。虽然没有什么技术含量,但画面着实焕然一新,也算作一点进步。
系统已经定名为babyos,翻译作宝贝/宝宝操作系统,则她画出来的界面叫做“涂鸦”也是情理之中的事儿,当然这是高级山寨涂鸦喽~
图形界面暂时定名为graffiti,译作“涂鸦”,虽然是髙仿真Ubuntu Gnome的一种情景模式,但实现方法与它毫无关系(当然是水的多了)。
注:此前babyos已经切换到800x600 24bit颜色显示模式——不为别的,只为与《30天》不同,或者内心深处希望比鬼子做的好一点,所以界面是髙仿真linux以与《30天》低仿真windows做比较~o(∩∩)o...哈哈
实验结果:
主要代码:
/************************************************************************* > File: graffiti.c > Describe: 系统叫baby,其界面名曰graffiti,取儿童涂鸦之意 > Author: 孤舟钓客 > Mail: guzhoudiaoke@126.com > Time: 2013年01月05日 星期六 00时29分31秒 ************************************************************************/ #include <graffiti.h> static u32 screen_cx; static u32 screen_cy; static BOOL init_graffiti() { screen_cx = get_screen_width(); screen_cy = get_screen_height(); return TRUE; } /* 绘制桌面背景 */ BOOL draw_background() { color24 old_color = set_color(RGB(background_color.r, background_color.g, background_color.b)); fill_rectangle(0, 0, screen_cx, screen_cy); set_color(old_color); return TRUE; } /* position 暂时只支持0或1,0表示在屏幕最上面画,1表示在最下面 */ BOOL draw_panel(u8 position) { s32 top, bottom, y; color24 old_color; if (position == 0) { top = 0; bottom = PANEL_HEIGHT; } else { bottom = screen_cy; top = bottom-PANEL_HEIGHT; } old_color = get_current_color(); for (y = top; y < bottom; y++) { set_color_t(panel_color[y-top]); fill_rectangle(0, y, screen_cx, 1); } set_color(old_color); return position; } /* 绘制一个窗口 */ BOOL draw_window(s32 left, s32 top, u32 width, u32 height) { s32 right, bottom, y, i; color24 old_color; if (width < MIN_WINDOW_WIDTH) width = MIN_WINDOW_WIDTH; right = left + width; bottom = top + height + W_HEAD_HEIGHT; y = top; i = 0; old_color = get_current_color(); /* 窗体头 */ for (i = 0; i < W_ROUND_RECT_HEIGHT; i++) { set_color_t(w_head_color[i]); fill_rectangle(left+w_round_rect_width[i], y++, width-w_round_rect_width[i]*2, 1); } set_color_t(w_head_color[0]); for (i = 0; i < W_ROUND_RECT_POINT_NUM; i++) { set_pixel(left+w_round_rect_border_points[i].x, top+w_round_rect_border_points[i].y); set_pixel(right-w_round_rect_border_points[i].x-1, top+w_round_rect_border_points[i].y); } for (; i < W_HEAD_HEIGHT; i++) { set_color_t(w_head_color[i]); fill_rectangle(left, y++, width, 1); } /* 窗体 */ set_color_t(w_boday_color); fill_rectangle(left, top+W_HEAD_HEIGHT, width, height-W_ROUND_RECT_HEIGHT); y = bottom - 1; for (i = 0; i < W_ROUND_RECT_HEIGHT; i++) { fill_rectangle(left+w_round_rect_width[i], y--, width-w_round_rect_width[i]*2, 1); } set_color_t(w_bottom_color); for (i = 0; i < W_ROUND_RECT_POINT_NUM; i++) { set_pixel(left+w_round_rect_border_points[i].x, bottom-w_round_rect_border_points[i].y-1); set_pixel(right-w_round_rect_border_points[i].x-1, bottom-w_round_rect_border_points[i].y-1); } /* 窗体边框 */ set_color_t(w_bottom_color); fill_rectangle(left+w_round_rect_border_points[0].x, bottom-1, width-w_round_rect_border_points[0].x*2, 1); for (i = 0; i < W_BORDER_WIDTH; i++) { set_color_t(w_border_color[i]); fill_rectangle(left+i, top+W_HEAD_HEIGHT, 1, height-W_ROUND_RECT_HEIGHT); fill_rectangle(right-i-1, top+W_HEAD_HEIGHT, 1, height-W_ROUND_RECT_HEIGHT); } /* 关闭按钮 */ set_color(old_color); return TRUE; } /* 安装graffiti界面 */ BOOL install_graffiti() { init_graffiti(); draw_background(); draw_panel(0); draw_panel(1); return TRUE; }
今天在处理问题时候,采用了读写锁,之前印象中记得读写锁在读大于写的场景下效率会比较高,但是并不是很明确,所以就乘机测试。具体测试代码如下所示:
package com.zhaming.lock; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class ConcurrentObject { private static Random random = new Random(); private final static int READ_NUM = 100; private final static int WRITE_NUM = 100; private int value; private ReadWriteLock lock = new ReentrantReadWriteLock(); private Lock locknew = new ReentrantLock(); public static void main(String[] args) throws InterruptedException { // int maxProcessor = Runtime.getRuntime().availableProcessors() * 2; 防止线程池大小过大,CPU过多的上下文切换导致的开销影响 int maxProcessor = READ_NUM + WRITE_NUM;// 线程池大小必须同 总共开启的对象 final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(maxProcessor); final CountDownLatch latch = new CountDownLatch(READ_NUM + WRITE_NUM);// 最后关闭线程池 final CyclicBarrier barrier = new CyclicBarrier(READ_NUM + WRITE_NUM);// 等待所有线程启动后并发读写 final ConcurrentObject concurrentObject = new ConcurrentObject(); for (int i = 0; i < READ_NUM; i++) { newFixedThreadPool.execute(new Runnable() { @Override public void run() { try { barrier.await(); } catch (Exception e) { e.printStackTrace(); } TimeCostUtils.start(TimeCostUtils.READ); concurrentObject.getValueLock(); TimeCostUtils.end(); latch.countDown(); } }); } for (int i = 0; i < WRITE_NUM; i++) { newFixedThreadPool.execute(new Runnable() { @Override public void run() { int nextInt = random.nextInt(1000); try { barrier.await(); } catch (Exception e) { e.printStackTrace(); } TimeCostUtils.start(TimeCostUtils.WRITE); concurrentObject.setValueLock(nextInt); TimeCostUtils.end(); latch.countDown(); } }); } latch.await(); newFixedThreadPool.shutdown(); // 系统推出前,关闭线程池及计算平均耗时、总耗时 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { @Override public void run() { display(); } })); } public static void display() { System.out.println("read cost average:" + (TimeCostUtils.getReadLong().get() / READ_NUM) + " ns"); System.out.println("write cost average:" + (TimeCostUtils.getWriteLong().get() / WRITE_NUM) + " ns"); } public int getValue() { lock.readLock().lock(); try { return value; } finally { lock.readLock().unlock(); } } public void setValue(int value) { locknew.lock(); try { this.value = value; } finally { locknew.unlock(); } } public int getValueLock() { locknew.lock(); try { return value; } finally { locknew.unlock(); } } public void setValueLock(int value) { lock.writeLock().lock(); try { this.value = value; } finally { lock.writeLock().unlock(); } } public synchronized int getValueSyn() { return value; } public synchronized void setValueSyn(int value) { this.value = value; } }
辅助工具类:
package com.zhaming.lock; import java.util.concurrent.atomic.AtomicLong; public class TimeCostUtils { private static AtomicLong readLong = new AtomicLong(); private static AtomicLong writeLong = new AtomicLong(); public final static String WRITE = "write"; public final static String READ = "read"; static ThreadLocal<TimesRecords> recordMap = new ThreadLocal<TimesRecords>(); public static void start(String prefix) { TimesRecords timesRecords = new TimesRecords(prefix, System.nanoTime()); recordMap.set(timesRecords); } public static void end() { TimesRecords timesRecords = recordMap.get(); long cost = System.nanoTime() - timesRecords.getCost(); // 计算每次的开销时间 if (timesRecords.getName().equals(WRITE)) { writeLong.addAndGet(cost); } else { readLong.addAndGet(cost); } } public static AtomicLong getReadLong() { return readLong; } public static AtomicLong getWriteLong() { return writeLong; } static class TimesRecords { private String name; private long cost; public TimesRecords(String name, long cost) { this.name = name; this.cost = cost; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getCost() { return cost; } public void setCost(long cost) { this.cost = cost; } } }
测试的JDK版本:
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02, mixed mode)
100 读,100写 采用读写锁
read cost average:48137 ns
write cost average:16932 ns
100 读,100写 采用sync
read cost average:20099 ns
write cost average:11639 ns
对比上面两组数据可以看出,在读写比相等的情况下,sync无论读写都比采用ReentrantReadWriteLock更有优势。
180 读,20写 采用读写锁
read cost average:21545 ns
write cost average:19466 ns
180 读,20写 采用sync
read cost average:12053 ns
write cost average:11556 ns
在改变读写比例后,采用sync的方式,数据基本没有什么变化,采用ReentrantReadWriteLock方式在读上性能有大幅度的提高,从第一次的48137降到了21545,但是写的性能从16932提升到19466,整体性能上还是比不上单纯采用sync的方式。
最后试试 写大于读的场景
20 读,180写 采用读写锁
read cost average:40149 ns
write cost average:13118 ns
20 读,180写 采用sync
read cost average:16268 ns
write cost average:15291 ns
在写大于读的情况下,sync的方式性能下降了,但是幅度并不是很大,采用读写锁模式情况下,写性能有一定的提升,这个提升的数值还是比不上单纯使用sync,而读性能基本没什么变化!
从上面的数据分析看sync的性能整体上再各种场景下是优于读写锁的,是否有可能是数值不是很大的原因呢?再扩大数值情况下看看数据:
20 读,580写 采用读写锁
read cost average:38021 ns
write cost average:13444 ns
数据基本没什么变化,读性能有一定的提升
20 读,580写 采用sync
read cost average:19331 ns
write cost average:13159 ns
从数据上看,还是完爆读写锁
预计其他场景下也差不多。如果读写锁效率不高,那么直接实施Lock看看效果如何
20 读,580写 采用ReentrantLock
read cost average:20388 ns
write cost average:14639 ns
性能上跟sync基本差不多,但是比读写锁好。
100 读,100写 采用ReentrantLock
read cost average:14270 ns
write cost average:15381 ns
性能上也基本没什么变化,到现在我们可以从数据上得出结论了,读写锁并不是最佳的选择,无论在何种场景下,最佳的选择还是sync
已有 0 人发表留言,猛击->>这里<<-参与讨论
ITeye推荐
- —软件人才免语言低担保 赴美带薪读研!—
1.准备工作
django-admin.py startproject web01 django-admin.py startapp tim python manage.py runserver
2.settings注册
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'tim', )
3.配置url
from django.conf.urls.defaults import patterns, include, url urlpatterns = patterns('', url(r'^tim/current/$','tim.views.current'), #映射views.py里的current url(r'^tim/plus/(\d{1,2})/$','tim.views.ahead'),#这里的数字部分,转化为元组,方便被offset取值 )
4.views视图文件,这里不用导入外部的html文件,所以不需要loader和Context了
#coding:utf8 from django.http import HttpResponse import datetime def current(req): now = datetime.datetime.now() html='现在时间是 %s' % now return HttpResponse(html) def ahead(req,offset): #这里的offset只是从url得到的传入值,变量名其实可以任意 try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = '%s 小时后,时间将变为 %s' % (offset,dt) #经过offset小时后,时间变为dt return HttpResponse(html)