注:以下代码为原创,若发现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)