海水正蓝

面朝大海,春暖花开
posts - 145, comments - 29, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

一个精美的个人作品集网站是吸引更多客户的最好方式。如果你正在建设个人作品集网站或者想重新设计的话可以参考本文收集的这些示例,相信这些精美的网站作品会带给你灵感。同时,这些网站中汇集了丰富的设计作品、素材和教程,能为你的设计带来很大的帮助。

Emotions by Mike

Emotions

Mark Forrester

Mark Forrester

Jeff Sarmiento

Jeff Sarmiento

Rawkes

Rawkes

Darren Hoyt

Darren Hoyt

Spoon Graphics

Spoon Graphics

Dawghouse Design Studios

Dawghouse

Adaptd

Adaptd

David Hellman

David Hellman

Tony Geer

Tony Geer

Octwelve

Octwelve

Finchley Web Design

Finchley

Jason Reed

Jason Reed

Squawk

Squawk

Adit Shukla

Adit Shukla

Albert Lo

Albert Lo

Digital Mash

Digital Mash

Alessandro Cavallo

Alessandro Cavallo

Ganato Design

Ganato Design

Cleverful

Cleverful

Design Disease

Design Disease

Mohammed Alaa

Mohammed Alaa

Jen Germann

Jen Germann

45 Royale

45 Royale

Viget

Viget

Shylands

Shylands

Function

Function

Electric Pulp

Electric Pulp

Luke Larsen

Luke Larsen

Jason Santa Maria

Jason Santa Maria

Matt Bango

Matt Bango

Concentric Studio

Concentric Studio

Vesess

Vesess

Pixel Haven

Pixel Haven

Winnie Lim

Winnie Lim

Nathan Carnes

Nathan Carnes

Guilherme Neumann

Neumann

Artworking

Artworking

Jason Duerr

Jason Duerr

Ed Merritt

Ed Merritt

Robbie Manson

Robbie Manson

Kind Company

Kind Company

Rikcat Industries

Rikcat Industries

Jamie Gregory

Jamie Gregory

Mark Boulton

Mark Boulton

Simone Maranzana

Simone Maranzana

The Things We Make

The Things We Make

EdDidIt

EdDidIt

Noe Design Studio

Noe

Evan Eckard

Evan Eckard

Level 9 Design

Level 9

Timothy van Sas

Timothy van Sas

Surefire

Surefire

Merix

Merix

Vibrant Drive

Vibrant Drive

Quo Consulting

Quo Consulting

New Concept

New Concept

Ash Web Media

Ash Web Media

Ecstatic Media

Ecstatic Media

Ordered List

Ordered List

Sidebar Creative

Sidebar Creative

Chris Garrett

Chris Garrett

Kyle Haskins

Kyle Haskins

GoodBytes

GoodBytes

Leigh Taylor

Leigh Taylor

Holds’worth Design

Holds'worth Design

Wake Interactive

Wake Interactive

Hydra Studio

Hydra Studio

FortySeven Media

FortySeven Media

Mario H. Coelho

Mario H. Coelho

1minus1

1minus1

You Love Us

You Love Us

Edit Studios

Edit Studios

Andrew Bradshaw

Andrew Bradshaw

Marius Roosendaal

Marius Roosendaal

Rory Story

Rory Story

Freshest

Freshest

Digital Base

Digital Base

Fling Media

Fling Media

Deaxon

Deaxon

SimpleBits

SimpleBits

Cabedge

Cabedge

Ameravant

Ameravant

ImageX Media

ImageX Media

Paravel Design

Paravel Design

Mint Idea

Mint Idea

thruSITES

thruSITES

31Three

31Three

Texelate

Texelate

Pixeleden

Pixeleden

Kyan Media

Kyan Media

Fulspectrum Media

Fulspectrum Media

Designchuchi

Designchuchi

Wishingline Design Studio

Wishingline Design Studio

Happy Cog

Happy Cog

Callender Creates

Callender Creates

Dreamten Studios

Dreamten Studios

EmaStudios

EmaStudios

Dairien Boyd

Dairien Boyd

Third & Grand

Third & Grand

OnWired

OnWired

最后,推荐一个很不错的收集个人作品集网站设计案例的网站foliofocus.com,去那寻找更多的设计灵感吧。

(编译来源:梦想天空  原文来自:101 Awesome Portfolio Sites

posted @ 2012-07-15 20:01 小胡子 阅读(143) | 评论 (0)编辑 收藏

jQuery 是一个非常优秀的 JavaScript 框架,使用简单灵活,同时还有许多成熟的插件可供选择,它可以帮助你在项目中加入漂亮的效果,其中之一就是幻灯片效果的实现,这是一种在有限的网页空间内 展示系列项目时非常好的方法。今天这篇文章要给大家分享的是60款很酷的 jQuery 幻灯片插件,相信里面一定会有你喜欢的。

Cloud Carousel (演示 | 下载)

Jqueryimage481 in Cool and Useful jQuery Image and Content Sliders and Slideshows

ShineTime (演示 | 下载)

Nivo Slider (演示 | 下载)

Interactive Photo Desk (演示 | 下载)

Beautiful Photo Stack Gallery with jQuery and CSS3 (演示 | 下载)

Micro Image Gallery: A jQuery Plugin (演示 | 下载)

Minimalistic Slideshow Gallery with jQuery (演示 | 下载)

Image Slider with Unique Effects (演示 | 下载)

Create image gallery in 4 lines of jQuery (演示 | 下载)

Slideshow with strip effects (演示 | 下载)

Nivo Zoom (演示 | 下载)

AD Gallery, gallery plugin for jQuery (演示 | 下载)

MLB.com Content Switcher with jQuery and CSS3 (演示 | 下载)

Create Scrollable Interface (演示 | 下载)

Animate Panning Slideshow with jQuery (演示 | 下载)

Image Scale Carousel (演示 | 下载)

Sudo Slider (演示 | 下载)

GALLERYVIEW (演示 | 下载)

Jquery Plugin MopSlider 2.4 (演示 | 下载)

jQuery Image Scroller (演示 | 下载)

Image Gallery Using jQuery and Flickr (演示 | 下载)

jQuery plugin: Wilq32.RotateImage (演示 | 下载)

jQZoom Evolution (演示 | 下载)

Photo gallery using jQuery and VisualLightBox (演示 | 下载)

Zoomimage (演示 | 下载)

YoxView (演示 | 下载)

Supersized (演示 | 下载)

AnythingSlider (演示 | 下载)

Photo Revealer (演示 | 下载)

Exposure (演示 | 下载)

Auto-Playing Featured Content Slider (演示 | 下载)

Horinaja (演示 | 下载)

S3 Slider (演示 | 下载)

Slide Deck (演示 | 下载)

Galleriffic (演示 | 下载)

Photo Gallery – Dark Theme (演示 | 下载)

jQuery morphing gallery (演示 | 下载)

Simple Accordion w/ CSS and jQuery (演示 | 下载)

Automatic Image Slider w/ CSS & jQuery (演示 | 下载)

Create a Slick and Accessible Slideshow Using jQuery (演示 | 下载)

Fancy Thumbnail Hover Effect w/ jQuery (演示 | 下载)

Coda Slider Effect (演示 | 下载)

Simple Controls Gallery (演示 | 下载)

Popeye (演示 | 下载)

Simple 演示 (演示 | 下载)

ImageFlow (演示 | 下载)

Moving Boxes (演示 | 下载)

SlideViewerPro (演示 | 下载)

Pirobox (演示 | 下载)

jQuery simple panorama viewer (演示 | 下载)

A Beautiful Apple-style Slideshow Gallery (演示 | 下载)

Flickr Photobar Gallery (演示 | 下载)

Step Carousel Viewer (演示 | 下载)

Zoom-Info (演示 | 下载)

Box Slider (演示 | 下载)

jQuery Panel Gallery (演示 | 下载)

Image Highlighting and Preview with jQuery (演示 | 下载)

Multimedia Gallery for Images, Video and Audio (演示 | 下载)

Awesome Mobile Image Gallery Web App (演示 | 下载)

您可能还喜欢

 

 

编译来源:梦想天空 ◆ 关注前端开发技术 ◆ 分享网页设计资源

原文来自:Cool and Useful jQuery Image and Content Sliders and Slideshows

posted @ 2012-07-15 19:58 小胡子 阅读(247) | 评论 (0)编辑 收藏

今天这篇文章收集了34个漂亮的应用程序后台管理界面分享给大家。这些界面都是来自 themeforest网站,虽然直接下载需要付费的,不过大部分都提供了在线预览,所以完全能够复制下来,有的提供了预览图,设计师可以根据预览图自己 设计。希望这些漂亮的后台管理界面设计案例能帮助到你。(有登录界面的,点击登录即可进入后台界面)

Flexy Admin


34个漂亮的应用程序后台管理系统界面

Broom Cupboard Admin Skin


34个漂亮的应用程序后台管理系统界面

Fresh CMS


34个漂亮的应用程序后台管理系统界面

Ultimate Admin Panel Solution


34个漂亮的应用程序后台管理系统界面

Titanium


34个漂亮的应用程序后台管理系统界面

Wide Admin


34个漂亮的应用程序后台管理系统界面

AP Admin Panel


34个漂亮的应用程序后台管理系统界面

Ninja Admin


34个漂亮的应用程序后台管理系统界面

Sleek Admin Skin


34个漂亮的应用程序后台管理系统界面

Pro Admin Template


34个漂亮的应用程序后台管理系统界面

您可能还喜欢



系列文章:34个漂亮的应用程序后台管理界面(系列一)

英文来源:Outstanding Admin Panels for Your Applications

编译来源:梦想天空 ◆ 关注前端开发技术 ◆ 分享网页设计资源

posted @ 2012-07-15 19:56 小胡子 阅读(241) | 评论 (0)编辑 收藏

基本介绍

  jQuery Tools 是基于 jQuery 开发的网站界面库,包含网站最常用的Tabs(选项卡)、Tooltip(信息提示)、Overlay(遮罩、弹窗)、Scrollable(滚动控 制)、Form Validator(表单验证)、Rangeinput(范围选择)、Dateinput(日期选择)等众多功能。jQuery Tools 提供了高自定义的API接口,能够帮助开发者非常容易的实现所需要的功能,带给用户更佳的使用体验。

 

 

  相比 jQuery UI,jQuery Tools 提供了作为网站应用更需要使用的功能,jQuery Tools 提供的功能分为三部分,分别是 UI Tools,Form Tools 和 Tools Box,下面会对每个功能模块分别作介绍,另外 jQuery Tools 要比 jQuery UI 的界面更精美,可定制性更好。除此之外,jQuery Tools 核心代码使用 GZIP 压缩后只有3.9KB,及时包括搜有的扩展功能也才14KB,要比 jQuery UI 轻量很多。

UI Tools

  UI Tools 部分包括Tabs、Tooltip、Overlay和Scrollable四个功能模块,各功能模块的Demo如下:

  Tabs(选项卡)

 

 

  1. Minimal setup for tabs
  2. Naming the tabs
  3. 4 different skins with CSS
  4. Using mouseover to switch tabs
  5. Making wizards with the tabs
  6. Making accordions with tabs
  7. Customizing the accordion effect
  8. Horizontal accordion using the tabs
  9. Multiple tabs and accordion instances
  10. Handling browsers back button
  11. Loading tab contents with ajax
  12. AJAXed tabs with history support
  13. Slideshow plugin for the tabs

  Tooltip(信息提示)

 

  

  1. Basics of using the tooltip
  2. Using any HTML inside the tooltip
  3. Imitating browsers default tooltip
  4. Using tooltips in form fields
  5. Using tooltips in tables or lists
  6. Custom tooltip effect
  7. Dynamic positioning of the tooltip

  Overlay(遮罩、弹窗)

 

 

  1. Minimal setup for overlay
  2. The apple effect for overlay
  3. Creating modal dialogs with overlay
  4. Opening overlays programmatically
  5. Overlays with different styles
  6. Loading external pages into overlay
  7. Multiple overlays on the same page
  8. Creating a customized overlay effect

  Scrollable(信息滚动)

 

 

  1. Minimal setup for scrollable
  2. A vertical scrollable
  3. A simple scrollable image gallery
  4. Gallery with multiple scrollables
  5. A scrollable registration wizard
  6. Scrollable plugins in action
  7. Browser back button navigation
  8. jQuery tools home page setup
  9. A complete navigational system
  10. Add and remove items from scrollable
  11. Customizing the scrolling animation

Form Tools

  Form Tools 部分包括Validator、Rangeinput和Dateinput三个功能模块,各功能模块的Demo如下:

 

 

  Validator(表单验证)

  1. Minimal setup for validator
  2. Custom input types and attributes
  3. Server & client-side validation
  4. Error Summary
  5. Validator events in action
  6. Localizing the validator

  Rangeinput(范围选择)

  1. Minimal setup for rangeinput
  2. A couple of vertical ranges
  3. Multiple small ranges
  4. A custom scrollbar for a DIV

  Dateinput(日期选择)

  1. Minimal setup for dateinput
  2. A large skin for Dateinput
  3. Customizing Dateinput behavior
  4. Prompting for start and end dates
  5. Calendar that is always available
  6. Localizing the Dateinput (french)

Tools Box

  Tools Box 部分包括Expose、Flashembed和Combinations三个功能模块,各功能模块的Demo如下:

 

 

  Expose(突出重点)

  1. Minimal setup for expose
  2. Styling the mask
  3. Exposing a form
  4. Exposing videos with a custom mask

  Flashembed(嵌入Flash)

  1. Basics of Flash embedding
  2. Flashembed and jQuery
  3. Loading flash on a mouse click
  4. Placing HTML on top of a flash object
  5. Handling old flash versions
  6. Flashembed and Flowplayer

  Combinations(整合功能)

  1. HTML5 form inside an overlay
  2. An artist’s portfolio
  3. Speeding up the portfolio

 

您可能还喜欢

 

 

本文链接:jQuery Tools:Web开发必备的 jQuery UI 库

编译来源:梦想天空 ◆ 关注前端开发技术 ◆ 分享网页设计资源

posted @ 2012-07-15 19:56 小胡子 阅读(273) | 评论 (0)编辑 收藏

工具提示(Tooltip)在网站中的一个小功能,但却有很重要的作用,常用于显示一些温馨的提示信息。如果网站中的工具提示功能做得非常有创意的话能够加深用户对网站印象。因此,今天这篇文章向大家推荐的20款优秀的 jQuery Tooltip 插件就是用于帮助你制作漂亮的工具提示效果。

1. Dynamic tooltip

flowplayer-dynamic-tooltip-jquery-tooltip-plugin-for-web-design

 

2. jGrowl

stanlemon-jgrowl-jquery-tooltip-plugin-for-web-design
 

3. jQuery Horizontal Tooltips Menu Tutorials

queness-horizontal-tooltips-menu-tutorials-jquery-tooltip-plugin-for-web-design

 

4. Coda Popup Bubble

jqueryfordesigners-coda-popup-bubble-jquery-tooltip-plugin-for-web-design

 

5. The Tooltip

banner js ajax freebies css

 

6. TipTip

code-drewwilson-tiptip-jquery-tooltip-plugin-for-web-design

 

7. (mb)Tooltip

pupunzi-mb-tooltip-jquery-tooltip-plugin-for-web-design

 

8. vTip

vertigo-project-vtip-jquery-tooltip-plugin-for-web-design
 

10. jQuery Ajax Tooltip

rndnext-blogspot-jquery-ajax-tooltip-jquery-tooltip-plugin-for-web-design

 

11. Digg-style post sharing tool with jQuery

queness-digg-style-post-sharing-tool-jquery-tooltip-plugin-for-web-design

 

12. Input Floating Hint Box

nicolae-namolovan-googlepages-input-hint-box-jquery-tooltip-plugin-for-web-design

 

13. Simpletip

simpletip-craigsworks-jquery-tooltip-plugin-for-web-design

 

14. qTip

craigsworks-qtip-jquery-tooltip-plugin-for-web-design

 

15. Orbital Tooltip

userfirst-orbital-jquery-tooltip-plugin-for-web-design

 

16. Tooltip

bassistance-tooltip-jquery-tooltip-plugin-for-web-design

 

17. tipsy

onehackoranother-tipsy-jquery-tooltip-plugin-for-web-design

 

18. Easiest jQuery Tooltip Ever

cssglobe-easiest-jquery-tooltip-ever-jquery-tooltip-plugin-for-web-design

 

19. Shiny Tooltips

 

20. BeautyTips

lullabot-beautytips-jquery-tooltip-plugin-for-web-design

 

您你可能还喜欢

 

posted @ 2012-07-15 19:40 小胡子 阅读(223) | 评论 (0)编辑 收藏

jQuery的易扩展性吸引了来自全球的开发者来共同编写jQuery插件。jQuery插件不仅能够增强网站的可用性,有效地改善用户体验,还可以大大减少开发时间。现在的jQuery插件很多,可以根据您的项目需要来选择。这里为您介绍20款非常不错的插件。


Creative Radical Web Typography

Lettering.js是一个轻量经的、易于使用的jQuery插件,可创造出极具个性的网页排版,是2010年最佳jQuery插件之一。 

演示 | 下载

New FancyMoves Jquery Product Slider

Jquery Product Slider是一款效果很不错的产品幻灯片插件。

演示 | 下载

Jquery Space Gallery

Jquery Space Gallery是一款很有空间感的图片库插件。

演示 | 下载

Fancy Thumbnail Hover Effect

这是一款非常不错的Hover效果插件。

演示 | 下载

Jquery Inline Form Validation

这是一款表单验证插件。

演示 | 下载

Site Switcher

这是一款站点切换插件。

演示 | 下载

AnythingSlider

这是一款效果很棒的幻灯片插件。

演示 | 下载

Jquery Tooltip Coda Bubble

这是一款简洁的jQuery信息提示插件。

演示 | 下载

Jquery Upload and Crop Image

这是一款图片上传和裁剪插件。

演示 | 下载

jQuery Carts

这是一款jQuery图表插件。

演示 | 下载

Twitter-like login box

这是一款类似Twitter登陆框效果的插件。

演示 | 下载

File Download

这是一款文件下载插件。

演示 | 下载

Polaroid Photo Viewer

这是一款宝丽莱效果图片浏览插件。

演示 | 下载

jquery Hover Sub Tag Cloud

这是一款子标签云显示插件。

演示 | 下载

Graph Visualization

这是一款图标可视化插件。

演示 | 下载

Show/Hide Jquery Panel

这是一款控制面板显示和隐藏的插件。

演示 | 下载

Drop Down with CSS and jQuery

这是一款下拉菜单插件。

演示 | 下载

Quick & Easy Zooming With jQuery – Zoomy

这是一款非常好用的缩放插件。

演示 | 下载

Horizontal Accordions

这是一款横向手风琴效果插件。

演示 | 下载

Flexible Rating

这是一款非常灵活的评分插件。

演示 | 下载

(编译来源:梦想天空  原文来自:20 Useful jQuery Plugins Every Developer Should Know About

posted @ 2012-07-15 19:39 小胡子 阅读(133) | 评论 (0)编辑 收藏

流体布局(一)

jQuery插件:jQuery.Waterfall.js, js的计算方法

jQuery1.4.4,IE8.0,opera,firefox,chrome测试通过

围观请点击:http://3vke.com

下载地址:Waterfall on github

1.使用方法:

①.加载jQuery库;
②.加载jQuery.Waterfull.js , 必须在jQuery库之后;
③.调用接口: $node.waterfull({/* 此处为设置选项, 可留空 */}) , 如:

$('#container').waterfall({})

2.设置选项:

{
    itemSelector:
'.post-home',   // 子元素id/class, 可留空
    columnCount:4,               // 列数,  纯数字, 可留空
    columnWidth:300              // 列宽度, 纯数字, 可留空
    isResizable: false,          // 自适应浏览器宽度, 默认false
    isAnimated: false,           // 元素动画, 默认false
    Duration: 500,               // 动画时间
    Easing: "swing",             // 动画效果, 配合 jQuery Easing Plugin 使用
    endFn: function(){}          // 回调函数
}

3.Ajax说明:

$.ajax({
    url: Url,
    beforeSend: function() {},
    success: function(date) {
        $(
'#container').append(date).waterfall({});
    }
})

流体布局(二)

固定宽度的流体布局的个人思路:参考文献:@qiqiboy javascript 图片预加载 

思路如下:

1.imgReady可以在图片没有加载完成之前,通过头信息获取到图片的大小(这种方法相当天才),于是我建立一个局部的数组,将图片高度储存起来:(div的高度亦可)

var argg= new Array()//例如有10篇文章,就是一个length=10的数组

2.通过浏览器的宽度,来判断一行可以放几张图(假定3张),再建立一个全局数组,保存数据:

var args= new Array()//初始化数据,全部设定为0 args=[0,0,0];

3.排序,用for循环,每一次通过比较argg[i]和args的最小值,来确定下一个div放置的位置,放完之后,把args的最小值重新赋值:

args[min]+=argg[i]

新版iphoto主题,采用如上方法布局,包含ajax后只有8Kb,相当廉价,新版首页观光地址:http://icold.me/photo

1.流体布局主题iPhoto新版首页观光地址:http://icold.me/photo

2.流体布局js计算方法以及js源代码下载:流体布局(三) 

 

 

流体布局(三)

本文主要写固定宽度流体布局中的处理办法(全文以iphoto主题为例)

1.先看看Html结构


<div id="container">
    
<div class="post-home">xxoo..</div>
    
<div class="post-home">xxoo..</div>
    
<div class="post-home">xxoo..</div>
    
<div class="post-home">xxoo..</div>
    
<div class="post-home">xxoo..</div>
    
</div>

#container宽度我设定为1050px, .post-home宽度设定为350px,具体的css就不写了(也就是3列)

2.js的算法


jQuery(document).ready(function($) {
  var args 
= [000];
  
/*储存已排列的最后3个.post-home的top值, 初始时为[0,0,0];
    没有储存left值, 因为left已经是知道的, [0,350,700];
  
*/
  sort($(
'#container > .post-home'));
  function sort(elem) { 
// elem是传入的DOM
    var r, // setTimeout相关变量
        m = 0,// 初始变量
        n = elem.length,// .post-home的数量
        topArgs = new Array(); // 建立一个局部数组
    Array.prototype.min = function() {
      
/*返回数组中最小值的序号
     0 ==>第一列(left = 0*350px)
     1 ==>第二列(left = 1*350px)
     2 ==>第三列(left = 2*350px)
      
*/
      var e,d 
= 0,b = this[0],c = this.length;
      
for (e = 1; e < c; e++) {
        
if (this[e] < b) {b = this[e];d = e}
      }
      
return d
    };
    Array.prototype.max 
= function() { // 返回数组中的最大值
      var d, b = this[0],c = this.length;
      
for (d = 1; d < c; d++) {
        
if (this[d] > b) {b = this[d]}
      }
      
return b
    };
    getHeight();
    function getHeight() {
      
if (m < n) { // 用来判断是不是获取了所有的.post-home的高度
        var $this = elem.eq(m), // 第m个.post-home
            h = parseInt($this.height()) + 16// 第m个.post-home高度 + 16, 16是与下一个div的距高
        topArgs.push(h); // 把第m个.post-home高度, 放到数组中去
        m++// m累加
        r = setTimeout(getHeight, 10// setTimeout来循环函数, 直到m==n 获取所有的高度
      }
      
if (m >= n) {
        clearTimeout(r); 
// 清除循环
        r = null;
        var d, e 
= topArgs.length; //初始化数据
        for (d = 0; d < e; d++) { // for循环来给topleft赋值
          var minNum = args.min(), // 获得args的最小值的序号
              newTop = args[minNum],// 获得args的最小值
          $that = elem.eq(d); // 第d个.post-home
          $that.css({ // for循环来给topleft赋值
            position: "absolute",
            top: newTop,
            left: 
350 * minNumber
          });
          args[minNum] 
= newTop + topArgs[d];
          
/*改变args数组最小值的大小
       这样args[minNum]就不是最小了
       而是这一列下一个.post-home的高度
       如此循环,下一个args[minNum],就是第二列的下一个.post-home的高度
     
*/
        }
        $(
'#container').css({
          height: args.max() 
//给$('#container')的高度赋值
        });
      }
    }
  }
});

3.最重要的问题

假如不能及时得到img的高度,将会错位,所以这里推荐再谈javascript图片预加载技术, 如果你嫌麻烦,可以用$(window).load(function(){})把上面的代码包括起来,$(window).load可以在图片加载完成之后执行内部的代码。


http://3vke.com/2012/03/09/%E6%B5%81%E4%BD%93%E5%B8%83%E5%B1%80%E6%8F%92%E4%BB%B6waterfall/

posted @ 2012-07-15 18:16 小胡子 阅读(6377) | 评论 (0)编辑 收藏

MySQL性能优化的21个最佳实践

今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 们程序员需要去关注的事情。当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能。这里,我们不会讲过 多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库。希望下面的这些优化技巧对你有用。

  1. 为查询缓存优化你的查询

大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中,这样,后续的相同的查询就不用操作表而直接访问缓存结果了。

这里最主要的问题是,对于程序员来说,这个事情是很容易被忽略的。因为,我们某些查询语句会让MySQL不使用缓存。请看下面的示例:


上面两条SQL语句的差别就是 CURDATE() ,MySQL的查询缓存对这个函数不起作用。所以,像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而 开启缓存。

  2. EXPLAIN 你的 SELECT 查询

使用 EXPLAIN 关键字可以让你知道MySQL是如何处理你的SQL语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。

EXPLAIN 的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的……等等,等等。

挑一个你的SELECT语句(推荐挑选那个最复杂的,有多表联接的),把关键字EXPLAIN加到前面。你可以使用phpmyadmin来做这个事。然后,你会看到一张表格。下面的这个示例中,我们忘记加上了group_id索引,并且有表联接:

当我们为 group_id 字段加上索引后:

我们可以看到,前一个结果显示搜索了 7883 行,而后一个只是搜索了两个表的 9 和 16 行。查看rows列可以让我们找到潜在的性能问题。

  3. 当只要一行数据时使用 LIMIT 1

当你查询表的有些时候,你已经知道结果只会有一条结果,但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。

在这种情况下,加上 LIMIT 1 可以增加性能。这样一样,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。

下面的示例,只是为了找一下是否有“中国”的用户,很明显,后面的会比前面的更有效率。(请注意,第一条中是Select *,第二条是Select 1)


  4. 为搜索字段建索引

索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么,请为其建立索引吧。

从上图你可以看到那个搜索字串 “last_name LIKE ‘a%’”,一个是建了索引,一个是没有索引,性能差了4倍左右。

另外,你应该也需要知道什么样的搜索是不能使用正常的索引的。例如,当你需要在一篇大的文章中搜索一个词时,如: “WHERE post_content LIKE ‘%apple%’”,索引可能是没有意义的。你可能需要使用MySQL全文索引 或是自己做一个索引(比如说:搜索关键词或是Tag什么的)

  5. 在Join表的时候使用相当类型的例,并将其索引

如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的。这样,MySQL内部会启动为你优化Join的SQL语句的机制。

而且,这些被用来Join的字段,应该是相同的类型的。例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样)


  6. 千万不要 ORDER BY RAND()

想打乱返回的数据行?随机挑一个数据?真不知道谁发明了这种用法,但很多新手很喜欢这样用。但你确不了解这样做有多么可怕的性能问题。

如果你真的想把返回的数据行打乱了,你有N种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是:MySQL会不得 不去执行RAND()函数(很耗CPU时间),而且这是为了每一行记录去记行,然后再对其排序。就算是你用了Limit 1也无济于事(因为要排序)

下面的示例是随机挑一条记录


  7. 避免 SELECT *

从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。

所以,你应该养成一个需要什么就取什么的好的习惯。

  8. 永远为每张表设置一个ID

我们应该为数据库里的每张表都设置一个ID做为其主键,而且最好的是一个INT型的(推荐使用UNSIGNED),并设置上自动增加的AUTO_INCREMENT标志。

就算是你 users 表有一个主键叫 “email”的字段,你也别让它成为主键。使用 VARCHAR 类型来当主键会使用得性能下降。另外,在你的程序中,你应该使用表的ID来构造你的数据结构。

而且,在MySQL数据引擎下,还有一些操作需要使用主键,在这些情况下,主键的性能和设置变得非常重要,比如,集群,分区……

在这里,只有一个情况是例外,那就是“关联表”的“外键”,也就是说,这个表的主键,通过若干个别的表的主键构成。我们把这个情况叫做“外键”。比 如: 有一个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程 ID叫“外键”其共同组成主键。

  9. 使用 ENUM 而不是 VARCHAR

ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。

如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。

MySQL也有一个“建议”(见第十条)告诉你怎么去重新组织你的表结构。当你有一个 VARCHAR 字段时,这个建议会告诉你把其改成 ENUM 类型。使用 PROCEDURE ANALYSE() 你可以得到相关的建议。

  10. 从 PROCEDURE ANALYSE() 取得建议

PROCEDURE ANALYSE() 会让 MySQL 帮你去分析你的字段和其实际的数据,并会给你一些有用的建议。只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的。

例如,如果你创建了一个 INT 字段作为你的主键,然而并没有太多的数据,那么,PROCEDURE ANALYSE()会建议你把这个字段的类型改成 MEDIUMINT 。或是你使用了一个 VARCHAR 字段,因为数据不多,你可能会得到一个让你把它改成 ENUM 的建议。这些建议,都是可能因为数据不够多,所以决策做得就不够准。

在phpmyadmin里,你可以在查看表时,点击 “Propose table structure” 来查看这些建议

一定要注意,这些只是建议,只有当你的表里的数据越来越多时,这些建议才会变得准确。一定要记住,你才是最终做决定的人。

  11. 尽可能的使用 NOT NULL

除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议,请往下看。

首先,问问你自己“Empty”和“NULL”有多大的区别(如果是INT,那就是0和NULL)?如果你觉得它们之间没有什么区别,那么你就不要使用NULL。(你知道吗?在 Oracle 里,NULL 和 Empty 的字符串是一样的!)

不要以为 NULL 不需要空间,其需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。 当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。

  12. Prepared Statements

Prepared Statements很像存储过程,是一种运行在后台的SQL语句集合,我们可以从使用 prepared statements 获得很多好处,无论是性能问题还是安全问题。

Prepared Statements 可以检查一些你绑定好的变量,这样可以保护你的程序不会受到“SQL注入式”攻击。当然,你也可以手动地检查你的这些变量,然而,手动的检查容易出问题, 而且很经常会被程序员忘了。当我们使用一些framework或是ORM的时候,这样的问题会好一些。

在性能方面,当一个相同的查询被使用多次的时候,这会为你带来可观的性能优势。你可以给这些Prepared Statements定义一些参数,而MySQL只会解析一次。

虽然最新版本的MySQL在传输Prepared Statements是使用二进制形势,所以这会使得网络传输非常有效率。

当然,也有一些情况下,我们需要避免使用Prepared Statements,因为其不支持查询缓存。但据说版本5.1后支持了。

在PHP中要使用prepared statements,你可以查看其使用手册:mysqli 扩展 或是使用数据库抽象层,如: PDO.


  13. 无缓冲的查询

正常的情况下,当你在当你在你的脚本中执行一个SQL语句的时候,你的程序会停在那里直到没这个SQL语句返回,然后你的程序再往下继续执行。你可以使用无缓冲查询来改变这个行为。

mysql_unbuffered_query() 发送一个SQL语句到MySQL而并不像mysql_query()一样去自动fethch和缓存结果。这会相当节约很多可观的内存,尤其是那些会产生大 量结果的查询语句,并且,你不需要等到所有的结果都返回,只需要第一行数据返回的时候,你就可以开始马上开始工作于查询结果了。

然而,这会有一些限制。因为你要么把所有行都读走,或是你要在进行下一次的查询前调用 mysql_free_result() 清除结果。而且, mysql_num_rows() 或 mysql_data_seek() 将无法使用。所以,是否使用无缓冲的查询你需要仔细考虑。

  14. 把IP地址存成 UNSIGNED INT

很多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果你用整形来存放,只需要4个字节,并且你可以有定长的字段。而且,这会为你带来查询上的优势,尤其是当 你需要使用这样的WHERE条件:IP between ip1 and ip2。

我们必需要使用UNSIGNED INT,因为 IP地址会使用整个32位的无符号整形。

而你的查询,你可以使用 INET_ATON() 来把一个字符串IP转成一个整形,并使用 INET_NTOA() 把一个整形转成一个字符串IP。在PHP中,也有这样的函数 ip2long() 和 long2ip()。

  15. 固定长度的表会更快

如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。 例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。

固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。

并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,他都是要分配那么多的空间。

使用“垂直分割”技术(见下一条),你可以分割你的表成为两个一个是定长的,一个则是不定长的。

  16. 垂直分割

“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。(以前,在银行做过项目,见过一张表有100多个字段,很恐怖)

示例一:在Users表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,你并不需要经常读取或是改 写这 个字段。那么,为什么不把他放到另外一张表中呢? 这样会让你的表有更好的性能,大家想想是不是,大量的时候,我对于用户表来说,只有用户ID,用户名,口令,用户角色等会被经常使用。小一点的表总是会有 好的性能。

示例二: 你有一个叫 “last_login” 的字段,它会在每次用户登录时被更新。但是,每次更新时会导致该表的查询缓存被清空。所以,你可以把这个字段放到另一个表中,这样就不会影响你对用户 ID,用户名,用户角色的不停地读取了,因为查询缓存会帮你增加很多性能。

另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去Join他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。

  17. 拆分大的 DELETE 或 INSERT 语句

如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。

Apache 会有很多的子进程或线程。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存。

如果你把你的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让你泊WEB服务Crash,还可能会让你的整台服务器马上掛了。

所以,如果你有一个大的处理,你定你一定把其拆分,使用 LIMIT 条件是一个好的方法。下面是一个示例:

18. 越小的列会越快

对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈。所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。

参看 MySQL 的文档 Storage Requirements 查看所有的数据类型。

如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。

当然,你也需要留够足够的扩展空间,不然,你日后来干这个事,你会死的很难看,参看Slashdot的例子(2009年11月06日),一个简单的ALTER TABLE语句花了3个多小时,因为里面有一千六百万条数据。

  19. 选择正确的存储引擎

在 MySQL 中有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊。酷壳以前文章《MySQL: InnoDB 还是 MyISAM?》讨论和这个事情。
MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都 无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。

InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。

下面是MySQL的手册
target=”_blank”MyISAM Storage Engine

InnoDB Storage Engine

  20. 使用一个对象关系映射器(Object Relational Mapper)

使用 ORM (Object Relational Mapper),你能够获得可靠的性能增涨。一个ORM可以做的所有事情,也能被手动的编写出来。但是,这需要一个高级专家。

ORM 的最重要的是“Lazy Loading”,也就是说,只有在需要的去取值的时候才会去真正的去做。但你也需要小心这种机制的副作用,因为这很有可能会因为要去创建很多很多小的查询反而会降低性能。

ORM 还可以把你的SQL语句打包成一个事务,这会比单独执行他们快得多得多。

目前,个人最喜欢的PHP的ORM是:Doctrine。

  21. 小心“永久链接”

“永久链接”的目的是用来减少重新创建MySQL链接的次数。当一个链接被创建了,它会永远处在连接的状态,就算是数据库操作已经结束了。而且,自 从我 们的Apache开始重用它的子进程后——也就是说,下一次的HTTP请求会重用Apache的子进程,并重用相同的 MySQL 链接。

PHP手册:mysql_pconnect()

在理论上来说,这听起来非常的不错。但是从个人经验(也是大多数人的)上来说,这个功能制造出来的麻烦事更多。因为,你只有有限的链接数,内存问题,文件句柄数,等等。

而且,Apache 运行在极端并行的环境中,会创建很多很多的了进程。这就是为什么这种“永久链接”的机制工作地不好的原因。在你决定要使用“永久链接”之前,你需要好好地考虑一下你的整个系统的架构。

转自:
http://3vke.com/2012/05/14/mysql%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E7%9A%8421%E4%B8%AA%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/

posted @ 2012-07-15 18:09 小胡子 阅读(128) | 评论 (0)编辑 收藏

一、起始之语

我一直都是在PC上折腾网页的,这会儿怎么风向周边捣鼓起手机网页开发呢?原因是公司原先使用Java开发的产品,耗了不少人力财力,但是最后的效果却不怎么好。因为,Android系统一套东西,iPhone又是新的一套,折腾死人呐。

于是总监发狠,让我把手上的活都交出去,专心折腾web版的,看看最后效果如何。

加上我觊觎手机上的开发学习很久了,于是,一拍即合,搞起了手机开发方面的学习。

分享是很好的提高自身学习的方法。因为分享过程中梳理了所学,往往会有些意想不到的心得与收获。如此利人利已的事情,自然乐意为之。于是,自己在文 章id > 2000 的这一历史性时刻,新建了一个“mobile相关”的分类目录,把移动相关的一些东西总结,整理,分享出去,大家共勉。

二、我的选择

显然,当下手机web开发移不开CSS3 + HTML5以及JavaScript。目前,也应运而生了很多开发的框架,有胶水层的,也有显示层的(不罗列)。因为个人偏好以及筛选,决定使用PhoneGap实现与设备相机,通讯录等交互,jQuery Mobile实现页面UI的显示以及相关交互。

如果时间足够,我想我会针对项目本身重新搞个更轻便灵活的交互框架。考虑到现实情况,还是决定使用他人的UI框架。

下截图为今儿个上午(2011-11-1 11:11)跑通的第一个PhoneGap下的Android手机程序:
PhoneGap下Android第一个页面程序效果展示截图 张鑫旭-鑫空间-鑫生活

不过PhoneGap是与胶水层打交道的东西,要说到这东西还需要些时日。我们可以先把目前投向与页面显示相关的UI框架上。例如,本文要说起的jQuery Mobile。

三、我眼中的jQuery Mobile

目前为止,jQuery Mobile的正式版还没有出来,但是这并不妨碍对其的使用。官方首页上说其代码轻量(lightweight code)。可能跟Sencha Touch相比确实轻量。但是,在我看来(本身为框架的原因),其实代码还是蛮啰嗦的(例如CSS文件min后有49K之多)。对于实际的项目而言,皮肤风格不可能几种并存的,所以,其a~e的五种模板选择实际有些多余,很多都是打酱油的命。

而且,实际项目中的设计师设计东东的时候不可能是总是跟着jQuery Mobile的UI来的。因此,我们难免会碰到对其模板进行修改或是新添加的情况。

不过,我可以确信的是,如果在个人网站或是其他一些非对外的中小项目上使用jQuery Mobile的话,一定会爽歪的!

然后,还有一点我得承认。jQuery Mobile的上手可比Sencha Touch快多了。其UI显示基本上就是基于HTML5的data-自定义属性来的,跟它的老爸爸jQuery一样,确实是write less, do more.

页面元素的UI显示完全可以根据HTML代码内容和属性而来,不需要任何额外的JavaScript代码或是CSS代码,有模有样的手机页面效果就可以出炉。而且,要出效果页面,你只要静下心花个1整天的时间把官方的介绍文档看一篇就可以了。真这么简单。

例如下面这个纯显示的页面们(PC建议使用Chrome浏览器围观)。
您可以狠狠地点击这里:jQuery Mobile的UI展示页面

手机可以访问以下地址:http://www.zhangxinxu.com/jq/mobile/

这是在桌面版opera 10.1 mobile下的显示效果:
默认进入:
demo页面效果1 张鑫旭-鑫空间-鑫生活

选择“文章搜索”项 → 点击搜索框后:
demo页面效果2 张鑫旭-鑫空间-鑫生活

如果是在Android系统或是iPhone上,渐变效果,平滑切换效果都会显露出来的。

上面加起来差不多有10多个HTML页面,捣鼓了几个小时就出来的,当然是在无敌模式下。为什么快呢?因为基本上没有动一点新的CSS代码或是JavaScript代码。直接write HTML即可。如果你对jQuery Mobile熟悉的话,可以更快。

语义化
要想使用jQuery Mobile,很重要的一点就是要注意语义化。到不是使用HTML5之类的标签(考虑到渐进增强,jQuery Mobile使用的还是XHTML时代的标签),而是div, p, ul ,li, h1~6等的使用。

jQuery Mobile标签下,不同的标签所对应的UI效果很多都已经定死了。例如:

<div data-role="header">     <h1>鑫空间-鑫生活</h1>     <a href="#" data-icon="arrow-r" data-iconpos="right">中文</a> </div>

上面这段data-roleheader的div中,h1标签不仅仅是个标题了,而是直接会修改当下页面的title值,因此,上面几行代码对应的页面的title就是“鑫空间-鑫生活”,即使你头部的title写的是“今天是小光棍节,呼啦啦~~”。

而后面的a标签文字虽然没有指定data-role="button",但是,谁叫他生在data-role="header"的div下呢,于是,它就是个显示按钮的命。而且,JMobile自动将其定位到右侧了。

语义化的标签决定了其位置,显示等。确实方便,但是有所限制。可谓有利有弊。

还有列表li标签中的第一个图片,会自动变成列表缩略图等,好多好多,你试一下就会发现这东西还是挺有意思的。

嘛,不过吗,不用急,冰冻三尺非一日之寒,什么东西都是慢慢积累的。才刚开始,说多了未必是好。所以,本文就唠叨这么多。

转自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]

posted @ 2012-07-14 22:47 小胡子 阅读(6575) | 评论 (5)编辑 收藏

本系列意在记录Windwos线程的相关知识点,包括线程基础、线程调度、线程同步、TLS、线程池等

 

信号量内核对象

信号量内核对象用来进行资源计数,它包含一个使用计数、最大资源数、当前资源计数。最大资源数表示信号量可以控制的最大资源数量,当前资源数表示信号当前可用的资源数量。

设想一个场景:需要开发一个服务器进程,最多同时运行5个线程来响应客户端请求,应该设计一个“线程池”。最开始的时候,5个线程都应该在等待状 态,如果有一个客户端请求到来,那么唤醒其中的一个线程以处理客户端请求,如果同时的请求数量为5,那么5个线程将全部投入使用,再多的请求应该被放弃。 也就是说,随着客户端请求的增加,当前资源计数随之递减。

我们可能需要这样的一个内核对象来实现这个功能:初始化5个线程并同时等待一个内核对象触发,当一个客户端请求到来时,试图触发内核对象,这样5个 线程中随机一个被唤醒,并且自动使内核对象变为未触发。外部判断上限是否到达5。表面看来似乎用“自动重置的事件对象”即可实现这个功能啊,为什么要涉及 到信号量呢?因为信号量还可以控制一次唤醒多少个线程!!而且这个例子只是信号量的一个用途,后面我们会看到一个更实际的用途。

总结一下,信号量内核对象是这样的一种对象:它维护一个资源计数,当资源计数大于0,处于触发状态;资源计数等于0时,处于未触发状态;资源计数不可能小于0,也绝不可能大于资源计数上限。下图展示了这种内核对象的特点:

image

如上图,只有资源计数>0时才是触发状态,资源=0时为未触发状态,而WaitForSingleObject成功将递减资源计数,调用ReleaseSemaphore将增加资源计数。

下面两个函数CreateSemaphoreCreateSemaphoreEx用于创建信号量对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HANDLE WINAPI CreateSemaphore(
  __in_opt  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,//内核对象安全描述符
  __in      LONG lInitialCount,//资源计数的初始值
  __in      LONG lMaximumCount,//资源计数的最大值
  __in_opt  LPCTSTR lpName //内核对象命名
);
 
HANDLE WINAPI CreateSemaphoreEx(
  __in_opt    LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
  __in        LONG lInitialCount,
  __in        LONG lMaximumCount,
  __in_opt    LPCTSTR lpName,
  __reserved  DWORD dwFlags,
  __in        DWORD dwDesiredAccess
);

任何进程可以用OpenSemaphore来得到一个命名的信号量:

1
2
3
4
5
HANDLE WINAPI OpenSemaphore(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  LPCTSTR lpName
);

线程通过调用ReleaseSemaphore来递增资源计数,不一定每次只递增1,可以设置递增任意值。当将要超过资源上限值的时候,ReleaseSemaphore会返回FALSE。

1
2
3
4
5
BOOL WINAPI ReleaseSemaphore(
  __in       HANDLE hSemaphore,
  __in       LONG lReleaseCount,//可以设置递增的值
  __out_opt  LPLONG lpPreviousCount//返回先前的资源计数
);

 

互斥量内核对象

互斥量(mutex)用来确保一个线程独占对一个资源的访问。互斥量包含一个使用计数、线程ID和一个递归计数,互斥量与关键段的行为几乎相同(因 为它记录了线程ID和递归计数,使得互斥量可以支持递归调用的情况)。互斥量的规则十分简单:如果线程ID为0(即没有线程独占它),那么它处于触发状 态,任何试图等待该对象的线程都将获得资源的独占访问;如果线程ID不为0,那么它处于未触发状态,任何试图等待该对象的线程都将等待。

可以使用CreateMutex或者CreateMutexEx创建互斥对象:

1
2
3
4
5
6
7
8
9
10
11
12
HANDLE WINAPI CreateMutex(
  __in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes,
  __in      BOOL bInitialOwner,//初始化对象的状态,如果传入FALSE则会初始化为触发状态,如果传入TRUE,那么对象的线程ID会被设置成当前调用线程,并初始化为未触发
  __in_opt  LPCTSTR lpName
);
 
HANDLE WINAPI CreateMutexEx(
  __in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes,
  __in_opt  LPCTSTR lpName,
  __in      DWORD dwFlags,
  __in      DWORD dwDesiredAccess
);

一如既往,OpenMutex用于打开一个已经命名的互斥量内核对象:

1
2
3
4
5
HANDLE WINAPI OpenMutex(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  LPCTSTR lpName
);

线程在获得对独占资源的访问权限之后,可以正常执行相关的逻辑,当需要释放互斥对象的时候可以调用ReleaseMutex

1
2
3
BOOL WINAPI ReleaseMutex(
  __in  HANDLE hMutex
);

互斥量与其他内核对象不同,它会记录究竟是哪个线程占用了共享资源,结合递归计数,同一个线程可以在获得共享资源之后继续访问共享资源,这个行为就像关键段一样。然而互斥量和关键段从本质上是不同的,关键段是用户模式的线程同步方法,而互斥量是内核模式的线程同步方式。

 

介绍完这两个内核对象后,我们思考一下前面在【Windows】线程漫谈——线程同步之Slim读/写锁中 设计的一个场景:有一个共享的队列,2个服务端线程负责读取队列中的条目以处理,2个客户端线程负责写入队列中的条目以使服务先端线程处理,当队列中没有 条目的时候应当挂起服务端线程,直到有条目进入时才被唤醒,另一方面,当队列已满时,客户端线程应当挂起直到服务端至少处理了一个条目,以释放至少一个条 目的空间。

现在我们来用信号量和互斥量来实现同样的功能,下面的流程图分别是客户端写入线程和服务端读取线程的逻辑:

1.首先创建一个互斥量对象m_hmtxQ,并初始化为未触发状态;之后创建一个信号量对象,并设置最大资源计数为队列的长度,初始化资源计数为0,正好表征队列元素的个数。

1
2
m_hmtxQ = CreateMutex(NULL,FALSE,NULL);
m_hsemNumElements = CreateSemaphore(NULL,0,nMaxElements,NULL);

2.设计客户端核心逻辑如下图:

image

WatiForSingleObject:试图获得队列的独占访问权限,对于这个队列无论是读还是写都应该是线程独占的。因此,使用互斥量对象来同步;

ReleaseSemaphore:试图增加一个资源计数,表征客户端想要向队列中增加一个元素,当然队列可能现在已经满了,对应的资源计数已达到 计数上限,此时ReleaseSemaphore会返回FALSE,这样客户端就不能像队列中插入元素。反之,如果ReleaseSemaphore返回 TRUE,表示队列没有满,客户端可以向队列中插入元素。

ReleaseMutex:无论客户端是否能够像队列中插入元素,在结束访问后,都应该释放互斥对象,以便其他线程能够进入临界资源。

3.设计服务端核心逻辑如下图:

image

WatiForSingleObject:试图获得队列的独占访问权限,对于这个队列无论是读还是写都应该是线程独占的。因此,使用互斥量对象来同步;

WaitForSingleObject(m_hsemNumElements…):试图检查信号量对象是否是触发状态。只有是触发状态的信号量对 象,线程才能进入;也就意味着:队列中只要有元素(资源>0,触发状态),服务端就能读取。反之,如果队列中没有元素(资源=0,未触发状态),服 务端将暂时不能访问队列,这时应该立即释放Mutex。

ReleaseMutex:无论客户端是否能够像队列中插入元素,在结束访问后,都应该释放互斥对象,以便其他线程能够进入临界资源。



原文:http://www.cnblogs.com/P_Chou/archive/2012/07/13/semaphore-and-mutex-in-thread-sync.html

posted @ 2012-07-13 22:54 小胡子 阅读(223) | 评论 (0)编辑 收藏

仅列出标题
共15页: First 上一页 7 8 9 10 11 12 13 14 15 下一页