Panda USB 隨身碟 免費病毒疫苗


全新!Panda USB 病毒疫苗
對抗病毒和惡意軟體的免費抗體
各種USB裝置的守護神
各種USB裝置的守護神!對抗病毒和惡意軟體的免費抗體!
立即享用
行動儲存裝置,
已經成為新一代的
惡意軟體溫床


隨身碟、數位相機、MP4播放器...
目前所有的USB裝置,
都有可能感染您的電腦。

請注意!
現在USB裝置的驅動程式裡面,
已經出現模擬AutoRun檔案的新型網路威脅

Panda USB 病毒疫苗是一個完全免費的反惡意軟體程式,能夠有效幫您對抗最新型的USB裝置威脅。
此疫苗是透過一套預防式的安全防護網,
來守護您的電腦以及行動儲存裝置。
 免費下載

影像捲動環繞 之 電玩畫面戲法


The wrapping image game trick

By Muammar©

解說 在電玩中所使用的讓 背景影像無休止的轉動之技巧




導言

你可曾想過電玩中的背景圖不斷的移動它到底有多長?
您必須注意到在某一時刻背景圖內容只是不斷的重複,這就是我們要學習這篇文章的重點.
兩天前, 我與我的孩子在公園散步時我注意到行人道上的磚塊排列方式是一個無止境的重複形狀,於是我決定用一個數學方法中來看這一問題。

幻覺





hypnosquare.gif
透過色彩與紋裡影像操作總是被使用在讓人產生錯覺的技法. 若要做出鋪磚錯覺效果來首先處理的第一個問題就是要讓圖片做出無縫連接 "tileable",以使其結束點能夠重複連接圖片產生連續的效果..
In other words, it's about placing a piece of texture next to each other without having a visible seam, and making sure not to have any eye-catching repeating spots in the overall picture.
It might be useful to say that not any picture will do, you need to have some sort of a repetitive pattern, at least at the edges of the picture.

現在,選擇圖片請確保包括兩個基本要求:
  1. 圖片的邊緣必須是 90° 角.
  2. 圖片邊緣不應該有光暈.

NYC.JPG
既然我們的圖片都準備好了,我們可平鋪就的方式有兩種選擇。 We might want to tile it only in one dimension, i.e., horizontally/vertically so the picture fits in a row/column, or we could make it completely tileable by making sure that all ends match up. However, if you're intending to make a fully tileable picture, you'd better make it a perfect square of a size based on a power of 2 (i.e., 2^5 = 32), for two main reasons:
  1. Many commercial imaging filters (most notably clouds) will create already seamless tiles, but only if the original image is based on a power of 2.
  2. Powers of two are easy to manage and check when it comes to pictures, and even your monitor resolution is based on a power of two!



背景

To make the picture tileable, the first thing you need to do is to offset it horizontally and/or vertically, preferably by 50% of its original dimensions. This is best demonstrated by means of a picture. So in a picture like shown below, the creepy alien seems to be nudged over from the picture to reappear on the other side of it. "Sorry Bob".
BOBs.JPG
Now that we have made sure the edges match seamlessly, let's see how the endless wrapping works.. We need to look at the picture in a different way, recognizing the overall image as a beam of columns and rows of pixels, those when meet will make a perfect cylinder.
ShiftedClips.JPG
Now, to make an illusion of a picture moving to the right, we simply iterate through the columns of the picture, taking the most right column or columns; depending on how smooth the movement of the picture should be (the more columns you take out in a single movement, the less smoothness the movement of the picture will have), we take out that column(s), shift the rest of the picture to exactly cover the gap created by the taken column(s), and then we reattach those columns back to the picture, but to the gap created in the beginning of the picture when we moved (Clip1) to cover for the taken out columns (Clip2) in the first place. The following pictures show the movement technique by indexing the pixels of a sample picture of a 4X4.
Matrix.JPG
Notice the shift of the indexes in the blue to move the respective image from left to right, and the green one to give the illusion of a downward moving picture. Also notice that if more than one column is moved, the series still maintains to keep ordered in a contiguous manner.

Using the Code

Ocean.JPG
I'm going to explain only the endless ocean solution as it covers the wrapping trick for both dimensions.
Note that you can change the direction of both samples by holding down the Control key and pressing the respective Arrow key.
To move the picture, we first need to clip it as explained above, and here is the function to do it:
 Collapse
private Bitmap Crop(Bitmap srcBitmap, Rectangle rectClip)
{
    Bitmap tmpBmp = new Bitmap(rectClip.Width, rectClip.Height);
    Graphics g = Graphics.FromImage(tmpBmp);

    g.DrawImage(srcBitmap, 0, 0, rectClip, GraphicsUnit.Pixel);
    g.Dispose();
    return tmpBmp;
}
The function takes the source bitmap as its first parameter, and the rectangle to cut out, considering the start location of the clipping and the dimensions, then returns that part as a Bitmap object.
We also use some user controls inherited from the PictureBox class to support background transparency.
 Collapse
using System;
using System.Windows.Forms;

namespace UI_Test
{
    public class TransparentPictureBox : PictureBox
    {
        public TransparentPictureBox()
        {
            this.SetStyle(ControlStyles.Opaque, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams parms = base.CreateParams;
                parms.ExStyle |= 0x20; 
                return parms;
            }
        }
    }
}
Once compiled, you'll see the control added to your solution components list at the top of the toolbox pane with the labelTransparentPictureBox.
Now, let's take a look at the entire code listing and discuss each part separately.
 Collapse
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Media;

namespace SampleGameII
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private enum Style
        {
            Left,
            Right,
            Up,
            Down
        }

        private void tmr_MoveBG_Tick(object sender, EventArgs e)
        {
            if (!chReverse.Checked)
                PIC1.Image = MoveImage((Bitmap)PIC1.Image.Clone(), iSpeed, sDirection);
            else
            {
                if (iSpeed >= Properties.Resources.Ocean.Width - iSpeed)
                    iSpeed = 3;
                else
                    iSpeed += 3;
                PIC1.Image = MoveImage(Properties.Resources.Ocean, iSpeed, sDirection);
            }
            Spaceship.Refresh();
        }


        private Bitmap Crop(Bitmap srcBitmap, Rectangle rectClip)
        {
            Bitmap tmpBmp = new Bitmap(rectClip.Width, rectClip.Height);
            Graphics g = Graphics.FromImage(tmpBmp);

            g.DrawImage(srcBitmap, 0, 0, rectClip, GraphicsUnit.Pixel);
            g.Dispose();
            return tmpBmp;
        }

        private Bitmap MoveImage(Bitmap srcBitmap, int iMargin, string sDirection)
        {
            Bitmap tmpBmp, Clip1, Clip2;
            tmpBmp = Clip1 = Clip2 = null;

            switch (sDirection)
            {
                case "Left":
                    {
                        tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                        Clip1 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(0, 0),
                                new Size(srcBitmap.Width - iMargin, srcBitmap.Height)));
                        Clip2 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(srcBitmap.Width - iMargin, 0),
                                new Size(iMargin, srcBitmap.Height)));

                        Graphics g = Graphics.FromImage(tmpBmp);

                        if (!chReverse.Checked)
                        {
                            g.DrawImage(Clip1, iMargin, 0, 
                               srcBitmap.Width - iMargin, srcBitmap.Height);
                            g.DrawImage(Clip2, 0, 0, iMargin, srcBitmap.Height);
                        }
                        else
                        {
                            g.DrawImage(Clip2, iMargin, 0, 
                               srcBitmap.Width - iMargin, srcBitmap.Height);
                            g.DrawImage(Clip1, 0, 0, iMargin, srcBitmap.Height);
                        }

                        g.Dispose();

                        break;
                    }
                case "Right":
                    {
                        tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                        Clip1 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(iMargin, 0),
                                new Size(srcBitmap.Width - iMargin, srcBitmap.Height)));
                        Clip2 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(0, 0),
                                new Size(iMargin, srcBitmap.Height)));

                        Graphics g = Graphics.FromImage(tmpBmp);


                        if (!chReverse.Checked)
                        {
                            g.DrawImage(Clip1, 0, 0, srcBitmap.Width - iMargin, 
                                        srcBitmap.Height);
                            g.DrawImage(Clip2, srcBitmap.Width - iMargin, 0, 
                                        iMargin, srcBitmap.Height);
                        }
                        else
                        {
                            g.DrawImage(Clip2, 0, 0, srcBitmap.Width - iMargin, 
                                        srcBitmap.Height);
                            g.DrawImage(Clip1, srcBitmap.Width - iMargin, 0, 
                                        iMargin, srcBitmap.Height);
                        }
                        g.Dispose();

                        break;
                    }
                case "Up":
                    {
                        tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                        Clip1 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(0, 0),
                                new Size(srcBitmap.Width, srcBitmap.Height - iMargin)));
                        Clip2 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(0, srcBitmap.Height - iMargin),
                                new Size(srcBitmap.Width, iMargin)));

                        Graphics g = Graphics.FromImage(tmpBmp);


                        if (!chReverse.Checked)
                        {
                            g.DrawImage(Clip1, 0, iMargin, srcBitmap.Width, 
                                        srcBitmap.Height - iMargin);
                            g.DrawImage(Clip2, 0, 0, srcBitmap.Width, iMargin);
                        }
                        else
                        {
                            g.DrawImage(Clip2, 0, iMargin, srcBitmap.Width, 
                                        srcBitmap.Height - iMargin);
                            g.DrawImage(Clip1, 0, 0, srcBitmap.Width, iMargin);
                        }
                        g.Dispose();

                        break;
                    }
                case "Down":
                    {
                        tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                        Clip1 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(0, iMargin),
                                new Size(srcBitmap.Width, srcBitmap.Height - iMargin)));
                        Clip2 = Crop(
                            srcBitmap,
                            new Rectangle(
                                new Point(0, 0),
                                new Size(srcBitmap.Width, iMargin)));

                        Graphics g = Graphics.FromImage(tmpBmp);


                        if (!chReverse.Checked)
                        {
                            g.DrawImage(Clip1, 0, 0, srcBitmap.Width, 
                                        srcBitmap.Height - iMargin);
                            g.DrawImage(Clip2, 0, srcBitmap.Height - iMargin, 
                                        srcBitmap.Width, iMargin);
                        }
                        else
                        {
                            g.DrawImage(Clip2, 0, 0, srcBitmap.Width, 
                                        srcBitmap.Height - iMargin);
                            g.DrawImage(Clip1, 0, srcBitmap.Height - iMargin, 
                                        srcBitmap.Width, iMargin);
                        }
                        g.Dispose();

                        break;
                    }
            }

            return tmpBmp;
        }


        int iSpeed;
        string sDirection;

        private void Form1_Load(object sender, EventArgs e)
        {
            sDirection = "Up";
            iSpeed = 3;
            tmr_MoveBG.Start();
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right
               || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
            {
                sDirection = e.KeyCode.ToString();


                iSpeed = 3;
                tmr_MoveBG.Start();

                Bitmap bm;

                    bm = new Bitmap(Properties.Resources.Spaceship2);


                if (e.KeyCode == Keys.Right)
                    bm.RotateFlip((System.Drawing.RotateFlipType)Enum.Parse(
                      typeof(System.Drawing.RotateFlipType), 
                      "Rotate90FlipNone", true));
                if (e.KeyCode == Keys.Left)
                    bm.RotateFlip((System.Drawing.RotateFlipType)Enum.Parse(
                      typeof(System.Drawing.RotateFlipType), 
                      "Rotate270FlipNone", true));
                if (e.KeyCode == Keys.Down)
                    bm.RotateFlip((System.Drawing.RotateFlipType)Enum.Parse(
                      typeof(System.Drawing.RotateFlipType), 
                      "Rotate180FlipNone", true));
                
                Spaceship.Image = bm;
            }
        }

        private void chReverse_CheckedChanged(object sender, EventArgs e)
        {
            if (!chReverse.Checked)
            {
                PIC1.Image = Properties.Resources.Ocean;
                tmr_MoveBG.Stop();
                iSpeed = 3;
                tmr_MoveBG.Start();
            }
        }

        private void tbSpeed_Scroll(object sender, EventArgs e)
        {
            tmr_MoveBG.Interval = 50 - (tbSpeed.Value * 5);
            lblSpeed.Text = "Speed: "+ (tbSpeed.Value+1).ToString();
        }
    }
}
The motion illusion is initiated and carried out using the tmr_MoveBG timer. The MoveImage function is called with every tick of the timer, passing a clone of the currently modified Image of the picture box and assigning it back to thePictureBox control to be passed again with the next tick.
 Collapse
private void tmr_MoveBG_Tick(object sender, EventArgs e)
{
    if (!chReverse.Checked)
        PIC1.Image = MoveImage((Bitmap)PIC1.Image.Clone(), iSpeed, sDirection);
    else
    {
        if (iSpeed >= Properties.Resources.Ocean.Width - iSpeed)
            iSpeed = 3;
        else
            iSpeed += 3;
        PIC1.Image = MoveImage(Properties.Resources.Ocean, iSpeed, sDirection);
    }
    Spaceship.Refresh();
}
The MoveImage function takes the source image as its first parameter as a Bitmap, along with the margin to clip and the desired direction to move to.
The direction parameter is evaluated through a switch case block to clip and redraw the right image, and then finally returns it to be set back to the PictureBox control, which will be taken again as a clone to be the new source image to pass to the function.
 Collapse
private Bitmap MoveImage(Bitmap srcBitmap, int iMargin, string sDirection)
{
    Bitmap tmpBmp, Clip1, Clip2;
    tmpBmp = Clip1 = Clip2 = null;

    switch (sDirection)
    {
        case "Left":
            {
                tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                Clip1 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(0, 0),
                        new Size(srcBitmap.Width - iMargin, srcBitmap.Height)));
                Clip2 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(srcBitmap.Width - iMargin, 0),
                        new Size(iMargin, srcBitmap.Height)));

                Graphics g = Graphics.FromImage(tmpBmp);

                if (!chReverse.Checked)
                {
                    g.DrawImage(Clip1, iMargin, 0, 
                          srcBitmap.Width - iMargin, srcBitmap.Height);
                    g.DrawImage(Clip2, 0, 0, iMargin, srcBitmap.Height);
                }
                else
                {
                    g.DrawImage(Clip2, iMargin, 0, 
                       srcBitmap.Width - iMargin, srcBitmap.Height);
                    g.DrawImage(Clip1, 0, 0, iMargin, srcBitmap.Height);
                }

                g.Dispose();

                break;
            }
        case "Right":
            {
                tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                Clip1 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(iMargin, 0),
                        new Size(srcBitmap.Width - iMargin, srcBitmap.Height)));
                Clip2 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(0, 0),
                        new Size(iMargin, srcBitmap.Height)));

                Graphics g = Graphics.FromImage(tmpBmp);


                if (!chReverse.Checked)
                {
                    g.DrawImage(Clip1, 0, 0, srcBitmap.Width - iMargin, srcBitmap.Height);
                    g.DrawImage(Clip2, srcBitmap.Width - iMargin, 0, 
                                iMargin, srcBitmap.Height);
                }
                else
                {
                    g.DrawImage(Clip2, 0, 0, srcBitmap.Width - iMargin, srcBitmap.Height);
                    g.DrawImage(Clip1, srcBitmap.Width - iMargin, 0, 
                                iMargin, srcBitmap.Height);
                }
                g.Dispose();

                break;
            }
        case "Up":
            {
                tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                Clip1 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(0, 0),
                        new Size(srcBitmap.Width, srcBitmap.Height - iMargin)));
                Clip2 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(0, srcBitmap.Height - iMargin),
                        new Size(srcBitmap.Width, iMargin)));

                Graphics g = Graphics.FromImage(tmpBmp);


                if (!chReverse.Checked)
                {
                    g.DrawImage(Clip1, 0, iMargin, srcBitmap.Width, 
                                srcBitmap.Height - iMargin);
                    g.DrawImage(Clip2, 0, 0, srcBitmap.Width, iMargin);
                }
                else
                {
                    g.DrawImage(Clip2, 0, iMargin, srcBitmap.Width, 
                                srcBitmap.Height - iMargin);
                    g.DrawImage(Clip1, 0, 0, srcBitmap.Width, iMargin);
                }
                g.Dispose();

                break;
            }
        case "Down":
            {
                tmpBmp = new Bitmap(srcBitmap.Width, srcBitmap.Height);
                Clip1 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(0, iMargin),
                        new Size(srcBitmap.Width, srcBitmap.Height - iMargin)));
                Clip2 = Crop(
                    srcBitmap,
                    new Rectangle(
                        new Point(0, 0),
                        new Size(srcBitmap.Width, iMargin)));

                Graphics g = Graphics.FromImage(tmpBmp);


                if (!chReverse.Checked)
                {
                    g.DrawImage(Clip1, 0, 0, srcBitmap.Width, srcBitmap.Height - iMargin);
                    g.DrawImage(Clip2, 0, srcBitmap.Height - iMargin, 
                                srcBitmap.Width, iMargin);
                }
                else
                {
                    g.DrawImage(Clip2, 0, 0, srcBitmap.Width, srcBitmap.Height - iMargin);
                    g.DrawImage(Clip1, 0, srcBitmap.Height - iMargin, 
                                srcBitmap.Width, iMargin);
                }
                g.Dispose();

                break;
            }
    }


    return tmpBmp;
}
In order to change the direction of the image, we capture the keyCode and assign it as a string to the sDirectionvariable and simply flip the spaceship image to match the new direction. Notice that the background image changes its direction as the sDirection variable value changes, for the timer is still running, and uses it to determine the moving direction.
 Collapse
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right
       || e.KeyCode == Keys.Up || e.KeyCode == Keys.Down)
    {
        sDirection = e.KeyCode.ToString();


        iSpeed = 3;
        tmr_MoveBG.Start();

        Bitmap bm;

            bm = new Bitmap(Properties.Resources.Spaceship2);


        if (e.KeyCode == Keys.Right)
            bm.RotateFlip((System.Drawing.RotateFlipType)Enum.Parse(
              typeof(System.Drawing.RotateFlipType), 
              "Rotate90FlipNone", true));
        if (e.KeyCode == Keys.Left)
            bm.RotateFlip((System.Drawing.RotateFlipType)Enum.Parse(
              typeof(System.Drawing.RotateFlipType), 
              "Rotate270FlipNone", true));
        if (e.KeyCode == Keys.Down)
            bm.RotateFlip((System.Drawing.RotateFlipType)Enum.Parse(
              typeof(System.Drawing.RotateFlipType), 
              "Rotate180FlipNone", true));
        
        Spaceship.Image = bm;
    }
}
The reversed effect is decided by checking the "Reverse Effect" check box which simply restarts the moving timer to use the new settings:
 Collapse
private void chReverse_CheckedChanged(object sender, EventArgs e)
{
    if (!chReverse.Checked)
    {
        PIC1.Image = Properties.Resources.Ocean;
        tmr_MoveBG.Stop();
        iSpeed = 3;
        tmr_MoveBG.Start();
    }
}
The new setting for the reverse effect is handled by switching the placement of the clips so that the bigger clip (Clip 1) takes the place of the smaller one (Clip 2) and vice versa, and hence the moving stretch effect to fit the clips in the wrong sizes.
 Collapse
if (!chReverse.Checked)
{
    g.DrawImage(Clip1, iMargin, 0, srcBitmap.Width - iMargin, srcBitmap.Height);
    g.DrawImage(Clip2, 0, 0, iMargin, srcBitmap.Height);
}
else
{
    g.DrawImage(Clip2, iMargin, 0, srcBitmap.Width - iMargin, srcBitmap.Height);
    g.DrawImage(Clip1, 0, 0, iMargin, srcBitmap.Height);
}
Finally, we determine the speed of the movement by increasing/decreasing the interval value of the timer.
 Collapse
private void tbSpeed_Scroll(object sender, EventArgs e)
{
    tmr_MoveBG.Interval = 50 - (tbSpeed.Value * 5);
    lblSpeed.Text = "Speed: "+ (tbSpeed.Value+1).ToString();
}
Of course, we could have increased the number of columns taken out in a clip, sacrificing some of the smoothness by increasing the margin in the MoveImage function.
 Collapse
PIC1.Image = MoveImage((Bitmap)PIC1.Image.Clone(), iSpeed, sDirection);
Note that the iSpeed value is predetermined in this example in the form_load event along with the sDirectionvalue.
 Collapse
private void Form1_Load(object sender, EventArgs e)
{
    sDirection = "Up";
    iSpeed = 3;
    tmr_MoveBG.Start();
}

Points of Interest

A major drawback of this technique is that the newly drawn image obscures the overlaying PictureBox image, and hence the timer keeps refreshing it with every tick, which generates this inconvenient flickering of the image.
 Collapse
private void tmr_MoveBG_Tick(object sender, EventArgs e)
{
    ...
    Spaceship.Refresh();
}






什麼是 USB 3.0


USB 3.0

USB 3.0支援全雙工,新增了5個觸點,兩條為數據輸出,兩條數據輸入,採用發送列表區段來進行數據發包,新的觸點將會並排在目前4個觸點的後方。USB 3.0暫定的供電標準為900mA,將支援光纖傳輸,一旦採用光纖其速度更有可能達到25Gbps。USB 3.0的設計相容USB 2.0與USB 1.1版本,並採用了三級多層電源管理技術,可以為不同設備提供不同的電源管理方案。[3]Intel的xHCI已經可以支援USB3.0的介面,向下相容USB2.0的介面。USB 3.0採用新的封包路由傳輸技術,線纜設計了8條內部線路,除VBusGND作為電源提供線外,剩餘3對均為數據傳輸線路其中保留了D+與D-兩條相容USB 2.0的線路,新增了SSRXSSTX專為新版所設的線路。USB 3.0的A介面繼續採用了與早先版本一樣的尺寸方案,只是內部觸點有變化。



在 Windows 7 安裝 Mircosoft AppLocale

很多人有這樣的經驗,安裝了其他語系的軟體時(例如 簡體中文軟體),會讓軟體產生一種亂碼的的情形,這時候會讓網友們完全看不懂軟體呈現的文字,而且在執行的時候會出現一些奇怪的錯誤訊息。
遇到這個情形,就要用 Mircosoft AppLocale 這套 Mircosoft 的語系解決軟體來轉換語系。
但在 Windows 7 安裝 AppLocale 時會出現權限錯誤請通知管理員的訊息。
--------------------------------------------------------------------------------------------------------------------------
解決方式:
1.將下載的安裝程式 Apploc.msi 檔複製到硬碟根目錄 (C:\ or D:\)。
2.以「管理員權限執行」「命令提示字元」,輸入 C:\apploc.msi or D:\apploc.msi
接下來就可以繼續安裝完畢了!

網路上操作方式教學:
http://www.cooltey.org/ping/applocale.htm

什麼是 Threads?為什麼要使用它?

什麼是 Threads?為什麼要使用它?


What are threads? Why use them?



歷史。

在早期電腦,所有程式基本上是單執行緒(single threaded)。您創建您的程式是藉由打孔卡或磁帶,提交您的紙牌給當地計算機中心,幾天後,您收到另一個紙牌,如果你是幸運的,所要求的結果。所有加工的一批重要的不是時間,先到先得,當你的程序運行,它已獨家使用計算機的時間。
事情已經提出。這個概念的多執行緒(multiple threads)第一次出現了共享系統,有超過一人可以登錄到一個中央主機電腦的一次。重要的是要確保處理時間的機器是相當分為所有用戶和操作系統的時間利用了“process”和“Thread”的概念。桌上型電腦看到了類似的進展。早期的DOS和Windows系統單任務(single tasking)。你的程式運行專門的機器,或根本沒有。日益複雜的應用程序,並不斷增加的需求在個人電腦上,特別是在高性能的圖形和網絡領域,多進程和多線程操作系統現在已是司空見慣。在電腦的多線程主要被使用的原因是,需要更好的性能和可用性

定義。

第一個概念的定義是 , 在 進程(process。大多數Windows 95,98和NT用戶有良好的直覺思想的過程是什麼。他們認為它的程序 , 可以在機器上運行,共存和共享CPU,磁盤和內存資源與其他程序。程序員都知道這個過程是一個調用的可執行代碼,這樣 , 該代碼有一個獨特的存在,並說明執行該過程在一個有序的執行方式。整體而言,執行過程中的孤立。他們使用的資源(內存,磁盤,I / O的CPU時間)的虛擬化,這樣的每一個進程都有自己的一套虛擬資源,觸及其他進程。該操作系統提供了這種虛擬技術。流程執行 模塊 的代碼。這可能是不相交的,在這個意義上說,可執行模塊的代碼 , 包括Windows資源管理器和Microsoft Word是不相交。不過,他們也可以共享,如案件DLL的。該代碼通常是一個DLL正在執行的範圍內 , 在許多不同的過程,往往同時進行。執行的指令是在整個進程之間沒有命令:Microsoft Word不停止打開文檔僅僅因為打印後台處理程序正在發送到打印機的東西!當然,在不同的過程相互作用,程序員必須對一個命令,一個中心問題將隨後闡述。
我們的下一個概念是 , 線程。線程被開發時 , 顯然 , 這是可取的應用程序的執行規定的行動更鬆散的時間排序的方式,可能是多套表演一次行動。在某些情況下的行動會造成相當大的延遲一個線程的執行(例如 : 等待用戶做什麼),這往往是可取的程序仍兼任執行其他操作(例如 , 後台拼寫檢查,或處理的傳入網絡消息)。不過,開銷創造一個全新的處理每個並行操作,然後有溝通的過程往往是太多的開銷。

一個例子。

如果我們要尋找一個很好的多線程例子,Windows 檔案總管(即Windows Shell))是一個很好的例子。當您去雙擊“我的電腦”,並通過點擊幾個子文件夾,創建新的視窗。現在一個窗口上執行複製操作。進度列彈出,以及特定的窗口不響應用戶輸入。但是,所有其它窗口還是可以動作。這就是多線程的本質。

時間截分

在大多數系統 , 支持多線程,可能有許多用戶同時請求作出的計算機系統。一般情況下 , 物理處理器數量在系統中是不到線程數可能並行運行。大多數系統的支持 時間截分,也稱為 先發製人的多任務( pre-emptive multitasking,為了解決這個問題。在一個系統 , 是時間切片,線程運行了一會兒,然後預設,即硬件計時器火災導致操作系統重新評估的主題應該怎樣經營,就可能停止執行當前正在運行的線程,並運行其他線程尚未執行最近。這使得即使是單一的處理器的機器上運行多個線程。基於PC的一時間片往往是對大約55毫秒長。



為什麼使用線程?

Threads不需改變一個程序的語法。它們只是改變時間的運作。因此,它們幾乎總是作為一個優雅的解決方案,性能相關的問題。下面是一些例子,在有些情況下可以使用線程:
  • 冗長的處理:當一個Windows應用程序是計算它不能處理任何更多的信息。因此,顯示器不能被更新。
  • 做後台處理:有些任務可能沒有時間重要,但需要一直執行下去。
  • 這樣做的I / O工作:I / O到磁盤或網絡可以有不可預知的延遲。線程允許您確保I / O延遲不延遲無關的部分應用程序。
所有這些例子有一個共同點:在程序中,某些操作可能招致大滯後或CPU佔用,但這種延誤或CPU使用率是不能接受的其他行動;他們需要服務的 現在。當然還有其他雜項福利,在這裡他們:
  • 製作使用多處理器系統:你不能指望一個應用程序只有一個線程利用兩個或多個處理器!
  • 高效時間分享:使用線程和進程優先級,可以確保每個人得到一個公平的分配CPU時間。
聰明的使用線程的曲折緩慢,笨重,不太響應程序到酥脆反應靈敏,高效,快捷的程序,並可以從根本上簡化各種性能和可用性問題。