﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-依睛(IT blog) 我回来了，PHP&lt;--&gt;C/C++ LINUX-随笔分类-Linux 学习库</title><link>http://www.cnitblog.com/guopingleee/category/5505.html</link><description>笨鸟
</description><language>zh-cn</language><lastBuildDate>Sun, 02 Oct 2011 08:40:38 GMT</lastBuildDate><pubDate>Sun, 02 Oct 2011 08:40:38 GMT</pubDate><ttl>60</ttl><item><title> Linux下c实现 IP转为域名</title><link>http://www.cnitblog.com/guopingleee/archive/2008/12/14/52595.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 14 Dec 2008 05:14:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/12/14/52595.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/52595.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/12/14/52595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/52595.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/52595.html</trackback:ping><description><![CDATA[
		<h1>
				<img height="16" alt="原创" src="http://blog.csdn.net/images/authorship.gif" width="15" border="0" /> <a href="http://blog.csdn.net/zuopai/archive/2008/04/02/2245473.aspx">Linux下c实现 IP转为域名</a><cite class="fav_csdnstylebykimi"><a class="fav_csdnstylebykimi" title="收藏到我的网摘中，并分享给我的朋友" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();"><font face="Tahoma" size="2">收藏</font></a></cite></h1>
		<div class="blogstory">
				<font size="2">都是入门级的例子<br />练手而已<br /><br />/***************************************************************************<br /> *   Copyright (C) 2008 by root   *<br />Linux下c实现   IP转为域名<br /> ***************************************************************************/<br />#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;errno.h&gt;<br />#include &lt;netdb.h&gt;<br />#include &lt;sys/types.h&gt;<br />#include &lt;netinet/in.h&gt;<br />#include &lt;sys/socket.h&gt;<br /><br />int main(int argc, char *argv[])<br />{<br />    struct sockaddr_in addr;<br />    struct hostent *host;<br />    char ipaddr[40];<br />    printf("请输入IP\n");<br />    scanf("%s",ipaddr);<br />    getchar();<br />    if(inet_aton(ipaddr,&amp;addr.sin_addr)!=0)<br />    {<br />        host=gethostbyaddr((char *)&amp;addr.sin_addr,4,AF_INET);<br />        <br />    }<br />    if(host==NULL)<br />    {<br />        fprintf(stderr,"NO address information of host %s\n",ipaddr);<br />        exit(1);<br />    }<br />    <br />    printf("HostName :%s\n",host-&gt;h_name);<br />    printf("主机别名: %s\n",host-&gt;h_aliases);<br />    printf("IP Address :%s\n",ipaddr);<br />    return 0;<br />    <br />} <br /></font>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/52595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-12-14 13:14 <a href="http://www.cnitblog.com/guopingleee/archive/2008/12/14/52595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下C实现通过域名得到IP收藏</title><link>http://www.cnitblog.com/guopingleee/archive/2008/12/14/52594.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 14 Dec 2008 05:09:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/12/14/52594.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/52594.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/12/14/52594.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/52594.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/52594.html</trackback:ping><description><![CDATA[
		<a href="http://blog.csdn.net/zuopai/archive/2008/04/01/2242510.aspx">Linux下C实现通过域名得到IP</a>
		<cite class="fav_csdnstylebykimi">
				<a class="fav_csdnstylebykimi" title="收藏到我的网摘中，并分享给我的朋友" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏<br /></a>
		</cite>
		<div class="blogstory">
				<font size="2">
						<br />一直想学Linux网络编程 <br />并且固执的要用c来写  认为这样才是最纯正牛x的<br />结果c写网络太难了.....<br />我想实现一个http的简单的get操作<br />居然没有找到一个例子<br />气死我了<br />Linux下的学习资料太少  那 我就来补充吧<br /><br /></font>
				<font size="2">gethostbyname（）</font>
				<br />真是相当简单 我终于可以自己写一个网络程序了<br /><font size="2">/***************************************************************************<br /> *   Copyright (C) 2008 by root   *<br />域名  转  IP地址<br /> ***************************************************************************/<br /><br /><br />#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;errno.h&gt;<br />#include &lt;netdb.h&gt;<br />#include &lt;sys/types.h&gt;<br />#include &lt;netinet/in.h&gt;<br /><br />int main(int argc, char *argv[])<br />{<br /> struct hostent *h;<br /> char hostname[40];<br /> printf("请输入域名\n");<br /> scanf("%s",hostname);<br /> getchar();<br /> if((h=gethostbyname(hostname))==NULL)<br /> {<br />     fprintf(stderr,"不能得到IP\n");<br />     exit(1);<br /> }<br /> printf("HostName :%s\n",h-&gt;h_name);<br /> printf("IP Address :%s\n",inet_ntoa(*((struct in_addr *)h-&gt;h_addr)));<br />  return EXIT_SUCCESS;<br />}</font></div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/52594.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-12-14 13:09 <a href="http://www.cnitblog.com/guopingleee/archive/2008/12/14/52594.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>线程同步</title><link>http://www.cnitblog.com/guopingleee/archive/2008/11/17/51553.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 17 Nov 2008 05:41:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/11/17/51553.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/51553.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/11/17/51553.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/51553.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/51553.html</trackback:ping><description><![CDATA[
		<p>这东西会很容易让新手看懂, 希望能对大家有助,<br /><br />线程同步, 只有实践才能学到东西, 理论看懂就行了, 动动手.<br />要少用全局变量.  我的代码都可以运行, 如有问题可联系我.<br /><br />我blog 上有联系方式.<br /><br />#include &lt;semaphore.h&gt;<br />#include &lt;unistd.h&gt;<br />#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;fcntl.h&gt;</p>
		<p>sem_t       sem_1;<br />sem_t       sem_2;<br /><br />void *thread2(void *arg)<br />{<br />    printf("sss\n");<br />    int i=-1;<br />    <br />    while(1)<br />    {<br />        sem_wait(&amp;sem_2);<br />        printf("11111value: %d\n", i+=2);<br />        sleep(1);<br />        sem_post(&amp;sem_1);<br />    }<br />}</p>
		<p>void *thread1(void *arg2)<br />{<br />    printf("222\n");<br />    int i=0;</p>
		<p>    while(1)<br />    {<br />        sem_post(&amp;sem_2);<br />        sem_wait(&amp;sem_1);<br />        printf("22222value: %d\n", i+=2);<br />        sleep(1);<br />    }<br />}</p>
		<p>
				<br />int main()<br />{<br />    pthread_t   t1;<br />    pthread_t   t2;</p>
		<p>    <br />    sem_init(&amp;sem_1, 0, 0);<br />    sem_init(&amp;sem_2, 0, 0);</p>
		<p>    pthread_create(&amp;t1, NULL, thread1, NULL);<br />    sleep(2);<br />    pthread_create(&amp;t2, NULL, thread2, NULL);<br />    <br />    pthread_join(t1, NULL);<br />    pthread_join(t2, NULL);<br />    <br />    return 0;<br />}</p>
		<p> </p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/51553.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-11-17 13:41 <a href="http://www.cnitblog.com/guopingleee/archive/2008/11/17/51553.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>线程同步(两个线程同步 加锁)</title><link>http://www.cnitblog.com/guopingleee/archive/2008/11/17/51552.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 17 Nov 2008 05:38:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/11/17/51552.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/51552.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/11/17/51552.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/51552.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/51552.html</trackback:ping><description><![CDATA[
		<p>
				<br />啊....同步终于搞清了, 晕死了....<br /><br />这东西真让我难解, 太笨了...可惜没有一本书来看, 时间太急.....<br /><br />两个线程同步 加锁<br /><br />#include &lt;stdio.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;pthread.h&gt;<br />#include &lt;errno.h&gt;<br />#include &lt;semaphore.h&gt;<br />#define BUFSIZE 4<br />#define NUMBER 8</p>
		<p>int sum_of_number=0;<br />int value=0; //全局变量, 要注意加锁</p>
		<p>
				<br />/*定义两个变量 信号量*/<br />sem_t write_res_number;<br />sem_t read_res_number;</p>
		<p> </p>
		<p>/* 初始化锁 ¯*/<br />pthread_mutex_t buffer_mutex=PTHREAD_MUTEX_INITIALIZER;</p>
		<p>static void *producer(void * arg)<br />{<br />    int i;<br />    <br />    for(i=0;i&lt;=12;i++)<br />    {<br />        /* 减少可写的资源数*/<br />        sem_wait(&amp;write_res_number);<br />        <br />        /* 加锁 */<br />        pthread_mutex_lock(&amp;buffer_mutex);<br />             <br />        value+=1;<br />        printf("procuder write: %d\n",value);<br />        <br />        /* 解锁 */<br />        pthread_mutex_unlock(&amp;buffer_mutex);<br />        <br />                sem_post(&amp;read_res_number);<br />    }<br />    return NULL;<br />}</p>
		<p>static void * consumer(void * arg)<br />{<br />    int i,num;<br />    <br />    for(i=0;i&lt;=12;i++)<br />    {<br />        sem_post(&amp;write_res_number);<br />        sem_wait(&amp;read_res_number);</p>
		<p>        pthread_mutex_lock(&amp;buffer_mutex);     <br />        value+=1;<br />        printf("read value %d.\n",value);<br />        <br />          pthread_mutex_unlock(&amp;buffer_mutex);      <br />    }        <br />    return NULL;<br />}</p>
		<p>int main(int argc,char ** argv)<br />{<br />     pthread_t p_tid;<br />    pthread_t c_tid;<br />    <br />    sem_init(&amp;write_res_number,0,0); <br />    sem_init(&amp;read_res_number,0,0);<br />    <br />       pthread_create(&amp;p_tid,NULL,producer,NULL);<br />    pthread_create(&amp;c_tid,NULL,consumer,NULL);<br />    <br />       pthread_join(p_tid,NULL);<br />    pthread_join(c_tid,NULL);<br />    <br />    pthread_mutex_destroy(&amp;buffer_mutex); /*ÊÕ»Ø»¥³âÁ¿×ÊÔ´*/<br />}<br /><br />在linux 下一样.<br />我在cygwin  运行结果: <br />$ gcc -lpthread -o th th<br />$ ./th<br />procuder write: 1<br />read value 2.<br />procuder write: 3<br />read value 4.<br />procuder write: 5<br />read value 6.<br />procuder write: 7<br />read value 8.<br />procuder write: 9<br />read value 10.<br />procuder write: 11<br />read value 12.<br />procuder write: 13<br />read value 14.<br />procuder write: 15<br />read value 16.<br />procuder write: 17<br />read value 18.<br />procuder write: 19<br />read value 20.<br />procuder write: 21<br />read value 22.<br />procuder write: 23<br />read value 24.<br />procuder write: 25<br />read value 26.<br />$<br /><br /></p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/51552.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-11-17 13:38 <a href="http://www.cnitblog.com/guopingleee/archive/2008/11/17/51552.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pthread_cond_wait() (转)</title><link>http://www.cnitblog.com/guopingleee/archive/2008/11/15/51512.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 15 Nov 2008 15:31:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/11/15/51512.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/51512.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/11/15/51512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/51512.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/51512.html</trackback:ping><description><![CDATA[
		<table style="BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
				<tbody>
						<tr>
								<td align="middle" bgcolor="#fed0e4">
										<font style="FONT-SIZE: 14pt" color="#d52847">
												<b>POSIX多线程中的pthread_cond_wait() 函数</b>
										</font>
								</td>
						</tr>
						<tr>
								<td>
										<table style="BORDER-COLLAPSE: collapse" bordercolor="#fed0e4" cellspacing="1" cellpadding="0" width="100%" border="1">
												<tbody>
														<tr>
																<td align="middle">
																		<table style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellspacing="0" cellpadding="0" width="100%" border="0">
																				<tbody>
																						<tr>
																								<td align="middle">
																										<table style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellspacing="0" cellpadding="0" width="100%" border="0">
																												<tbody>
																														<tr>
																																<td>
																																		<div id="art" style="MARGIN: 15px">  <br /><br />由于工作站软件的移植牵涉到这方面的内容, 搜一最近一直在学习Linux线程方面的知识!由于&lt;Beginning  the Linux programming&gt;这本书上没有将条件变量的问题,所以不能理解的一个函数就是pthread_cond_wait().<br />    今天终于有点明白了,赶快记下心得!<br />    条件变量的结构为pthread_cond_t，函数pthread_cond_init（）被用来初始化一个条件变量。它的原型为： 
<p class="code">　　extern int pthread_cond_init __P ((pthread_cond_t *__cond,__const pthread_condattr_t *__cond_attr));</p><p>　　其中cond是一个指向结构pthread_cond_t的指针，cond_attr是一个指向结构pthread_condattr_t的指针。结构 pthread_condattr_t是条件变量的属性结构，和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用，默认值是 PTHREAD_ PROCESS_PRIVATE，即此条件变量被同一进程内的各个线程使用。注意初始化条件变量只有未被使用时才能重新初始化或被释放。释放一个条件变量的函数为pthread_cond_destroy（pthread_cond_t cond）。　</p><p>    也可以静态的初始化条件变量</p><p>     pthread_cond_t my_condition = PTHREAD_COND_INITIALIZER;<br /></p><p>　　<font style="BACKGROUND-COLOR: #ff99ff">函数pthread_cond_wait（）使线程阻塞在一个条件变量上。</font>它的函数原型为：</p><p class="code">　　extern int pthread_cond_wait __P ((pthread_cond_t *__cond,pthread_mutex_t *__mutex));</p><p>　　 调用这个函数时,线程解开mutex指向的锁并被条件变量cond阻塞。线程可以被函数pthread_cond_signal和函数 pthread_cond_broadcast唤醒线程被唤醒后，它将重新检查判断条件是否满足，如果还不满足，一般说来线程应该仍阻塞在这里，被等待被下一次唤醒。这个过程一般用while语句实现。</p><p>    通过下面的程序来理解:</p><p>__________________华丽的CODE分割线_________________________<br /></p><p>#include &lt;pthread.h&gt;<br />#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br /><br />pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /*初始化互斥锁*/<br />pthread_cond_t cond = PTHREAD_COND_INITIALIZER;  //初始化条件变量 <br /><br />void *thread1(void *);<br />void *thread2(void *);<br /><br />int i=1;<br />int main(void)<br />{<br />        pthread_t t_a;<br />        pthread_t t_b;<br />        pthread_create(&amp;t_a,NULL,thread1,(void *)NULL);/*创建进程t_a*/<br />        pthread_create(&amp;t_b,NULL,thread2,(void *)NULL); /*创建进程t_b*/<br />        pthread_join(t_b, NULL);/*等待进程t_b结束*/<br />        pthread_mutex_destroy(&amp;mutex);<br />        pthread_cond_destroy(&amp;cond);<br />         exit(0);<br />}<br /><br />void *thread1(void *junk)<br />{<br />        for(i=1;i&lt;=9;i++)<br />        {<br />             pthread_mutex_lock(&amp;mutex);//<br />             if(i%3==0)<br />            <font style="BACKGROUND-COLOR: #ff99cc">     pthread_cond_signal(&amp;cond);/*条件改变，发送信号，通知t_b进程*/<br /></font>              else       <br />                  printf("thead1:%d\n",i);<br />              pthread_mutex_unlock(&amp;mutex);//*解锁互斥量*/<br />              printf("Up Unlock Mutex\n");      <br />              sleep(1);<br />        }<br /><br />}<br /><br />void *thread2(void *junk)<br />{<br />        while(i&lt;9)<br />        {<br />              pthread_mutex_lock(&amp;mutex);<br /><br />            if(i%3!=0)<br />            <font style="BACKGROUND-COLOR: #ff99cc">       pthread_cond_wait(&amp;cond,&amp;mutex);/*等待*/</font><font style="BACKGROUND-COLOR: #ff9933"><br /></font>            printf("thread2:%d\n",i);<br />            pthread_mutex_unlock(&amp;mutex);<br />            printf("Down Ulock Mutex\n");<br /><br />            sleep(1);<br />                }<br /><br />}<br /></p><p>___________________至关重要的绚烂的结果分割线_________________</p><p>thead1:1<br />Up Unlock Mutex<br />thead1:2<br />Up Unlock Mutex<br />Up Unlock Mutex<br />thread2:3<br />Down Ulock Mutex<br />thead1:4<br />Up Unlock Mutex<br />thead1:5<br />Up Unlock Mutex<br />Up Unlock Mutex<br />thread2:6<br />Down Ulock Mutex<br />thead1:7<br />Up Unlock Mutex<br />thead1:8<br />Up Unlock Mutex<br />Up Unlock Mutex<br />thread2:9<br />Down Ulock Mutex<br /><br />_________________HOW IT WORKS________<br /><br />i不是三的倍数的时候.</p><p>thread2条件变量阻塞,释放Mutex</p><p>thread1加锁,打印thread1:i,释放锁,打印"Up Unlock Mutex"</p><p>i为3的倍数的时候,</p><p>thread1,加锁,条件变量通知,唤醒条件变量阻塞线程,打印"Up Unlock Mutex"</p><p>thread2,被唤醒,加锁,打印"thread2:i",释放锁,打印"Down Ulock Mutex"</p><p><br /></p><p>    所以说函数pthread_cond_wait()调用时,不仅对条件变量起作用,还对互斥锁有作用!</p><br /><p>++++++++++++++++唯美的好书推荐线++++++++++++</p><p>"Beiginning Linux Programming" by Neil Matthrew &amp; Richard Stones</p><p>You can choose the English version or Chinese version, but I recommend the English one. Maybe it' easier to understand what the authers say than the Chinese one ,  even if you're Chinese.<br /></p><br /></div>
																																</td>
																														</tr>
																												</tbody>
																										</table>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/51512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-11-15 23:31 <a href="http://www.cnitblog.com/guopingleee/archive/2008/11/15/51512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>fstat printf用法</title><link>http://www.cnitblog.com/guopingleee/archive/2008/11/14/51432.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 14 Nov 2008 08:13:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/11/14/51432.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/51432.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/11/14/51432.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/51432.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/51432.html</trackback:ping><description><![CDATA[
		<dl class="code">
				<dt>C/C++ code 
</dt>
				<dd>
						<pre>
								<div>
										<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000">
 * mstat.c - Naive stat(1) program
</span>
										<span style="COLOR: #008000">*/</span>
										<span style="COLOR: #000000">

#include </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">unistd.h</span>
										<span style="COLOR: #000000">&gt;</span>
										<span style="COLOR: #000000">
#include </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">sys</span>
										<span style="COLOR: #000000">/</span>
										<span style="COLOR: #000000">types.h</span>
										<span style="COLOR: #000000">&gt;</span>
										<span style="COLOR: #000000">
#include </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">sys</span>
										<span style="COLOR: #000000">/</span>
										<span style="COLOR: #000000">stat.h</span>
										<span style="COLOR: #000000">&gt;</span>
										<span style="COLOR: #000000">
#include </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">fcntl.h</span>
										<span style="COLOR: #000000">&gt;</span>
										<span style="COLOR: #000000">
#include </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">time.h</span>
										<span style="COLOR: #000000">&gt;</span>
										<span style="COLOR: #000000">
#include </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">stdlib.h</span>
										<span style="COLOR: #000000">&gt;</span>
										<span style="COLOR: #000000">
#include </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">stdio.h</span>
										<span style="COLOR: #000000">&gt;</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">int</span>
										<span style="COLOR: #000000"> main(</span>
										<span style="COLOR: #0000ff">int</span>
										<span style="COLOR: #000000"> argc, </span>
										<span style="COLOR: #0000ff">char</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #000000">**</span>
										<span style="COLOR: #000000">argv)
{
    </span>
										<span style="COLOR: #0000ff">struct</span>
										<span style="COLOR: #000000"> stat buf;
    mode_t mode;
    </span>
										<span style="COLOR: #0000ff">char</span>
										<span style="COLOR: #000000"> type[</span>
										<span style="COLOR: #800080">80</span>
										<span style="COLOR: #000000">];
    </span>
										<span style="COLOR: #0000ff">int</span>
										<span style="COLOR: #000000"> fd;
    
    </span>
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000"> validate the command line </span>
										<span style="COLOR: #008000">*/</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(argc </span>
										<span style="COLOR: #000000">!=</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #800080">2</span>
										<span style="COLOR: #000000">){
        puts(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">USAGE: mstat {file}</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
        exit(EXIT_FAILURE);
    }
    
    </span>
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000"> open the file</span>
										<span style="COLOR: #008000">*/</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">((fd </span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000"> open(argv[</span>
										<span style="COLOR: #800080">1</span>
										<span style="COLOR: #000000">], O_RDONLY))</span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #800080">0</span>
										<span style="COLOR: #000000">){
        perror(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">open</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
        exit(EXIT_FAILURE);
    }
    
    </span>
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000"> get files stats </span>
										<span style="COLOR: #008000">*/</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">((fstat(fd, </span>
										<span style="COLOR: #000000">&amp;</span>
										<span style="COLOR: #000000">buf)) </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #800080">0</span>
										<span style="COLOR: #000000">) {
        perror(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">fstat</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
        exit(EXIT_FAILURE);
    }
    mode </span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000"> buf.st_mode;
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">     FILE: %s\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,argv[</span>
										<span style="COLOR: #800080">1</span>
										<span style="COLOR: #000000">]);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">    INODE: %ld\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,buf.st_ino);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">   DEVICE: %d,%d\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,major(buf.st_dev), minor(buf.st_dev));
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">     MODE: %#o\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,mode </span>
										<span style="COLOR: #000000">&amp;</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #000000">~</span>
										<span style="COLOR: #000000">(S_IFMT));
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">    LINKS: %d\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,buf.st_nlink);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">      UID: %d\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,buf.st_uid);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">      GID: %d\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,buf.st_gid);
    </span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(S_ISLNK(mode))
        strcpy(type, </span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">Symbolic line</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    </span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(S_ISREG(mode))
        strcpy(type,</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">Regular file</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    </span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(S_ISDIR(mode))
        strcpy(type,</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">Directory</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    </span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(S_ISCHR(mode))
        strcpy(type,</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">Character device</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    </span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(S_ISBLK(mode))
        strcpy(type,</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">Block device</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    </span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(S_ISFIFO(mode))
        strcpy(type,</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">FIFO</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    </span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(S_ISSOCK(mode))
        strcpy(type,</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">Socket</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    </span>
										<span style="COLOR: #0000ff">else</span>
										<span style="COLOR: #000000">
        strcpy(type,</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">Unknow type</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">     TYPE: %s\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,type);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">     SIZE: %ld\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,buf.st_size);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000"> BLK SIZE: %ld\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,buf.st_blksize);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">   BLOCKS: %d\n</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,(</span>
										<span style="COLOR: #0000ff">int</span>
										<span style="COLOR: #000000">)buf.st_blocks);
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000"> ACCESSED: %s</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,ctime(</span>
										<span style="COLOR: #000000">&amp;</span>
										<span style="COLOR: #000000">buf.st_atime));
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000"> MODIFIED: %s</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,ctime(</span>
										<span style="COLOR: #000000">&amp;</span>
										<span style="COLOR: #000000">buf.st_mtime));
    printf(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">  CHANGED: %s</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">,ctime(</span>
										<span style="COLOR: #000000">&amp;</span>
										<span style="COLOR: #000000">buf.st_ctime));
    
    </span>
										<span style="COLOR: #008000">/*</span>
										<span style="COLOR: #008000"> close the file </span>
										<span style="COLOR: #008000">*/</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #0000ff">if</span>
										<span style="COLOR: #000000">(close(fd) </span>
										<span style="COLOR: #000000">&lt;</span>
										<span style="COLOR: #000000">
										</span>
										<span style="COLOR: #800080">0</span>
										<span style="COLOR: #000000">) {
        perror(</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #800000">close</span>
										<span style="COLOR: #800000">"</span>
										<span style="COLOR: #000000">);
        exit(EXIT_FAILURE);
    }
    
    exit(EXIT_SUCCESS);
}



</span>
								</div>
						</pre>
				</dd>
		</dl>
		<br />
		<br />这个是linux编程指南2里面的例子。两个问题： <br />1.strcpy()不是该#include &lt;string.h&gt;才能用么？ <br />2.printf("    MODE: %#o\n",mode &amp; ~(S_IFMT));//%#o是什么意思？<img src ="http://www.cnitblog.com/guopingleee/aggbug/51432.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-11-14 16:13 <a href="http://www.cnitblog.com/guopingleee/archive/2008/11/14/51432.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>fstat、stat和lstat 区别(转)</title><link>http://www.cnitblog.com/guopingleee/archive/2008/11/13/51411.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Thu, 13 Nov 2008 14:27:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/11/13/51411.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/51411.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/11/13/51411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/51411.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/51411.html</trackback:ping><description><![CDATA[
		<p>stat系统调用系列包括了fstat、stat和lstat，它们都是用来返回“相关文件状态信息”的，三者的不同之处在于设定源文件的方式不同。</p>
		<p>
				<strong>1</strong>
		</p>
		<p>首先隆重介绍的是一个非常重要的”VIP”人物，他是fstat, stat和lstat三者都要用到的一个结构体类型，名字叫做struct stat。可以说，没有这个struct stat的支持，上述三个系统调用将寸步难行。</p>
		<p>
				<span id="more-500">
				</span>
		</p>
		<p>这个struct stat结构体在不同的UNIX/Linux系统中的定义是有小的区别的，但你完全不用担心，这并不会影响我们的使用。</p>
		<p>在struct stat结构体中我们常用的且各个平台都一定有的域是：</p>
		<p>
				<span style="COLOR: #ff6600">
						<strong>st_mode 文件权限和文件类型信息 <span style="COLOR: #000000">（记住这个黑体橘红色）</span><br /></strong>
				</span>
		</p>
		<p>st_ino   与该文件关联的inode</p>
		<p>st_dev   保存文件的设备</p>
		<p>st_uid   文件属主的UID号</p>
		<p>st_gid   文件属主的GID号</p>
		<p>st_atime 文件上一次被访问的时间</p>
		<p>st_ctime 文件的权限、属主、组或内容上一次被修改的时间</p>
		<p>st_mtime 文件的内容上一次被修改的时间。（和st_ctime的不同之处显而易见）</p>
		<p>st_nlink  该文件上硬连接的个数</p>
		<p>我分别提取了solaris（UNIX）和fedora（Linux）的struct stat结构体的原始定义：大家可以自己比对一下便可以发现两者确实有所不同，但主要的域是完全相同的。</p>
		<p>
				<span style="COLOR: #3366ff">
						<strong>solaris的struct stat定义：</strong>
				</span>
		</p>
		<p>struct stat {<br />dev_t           st_dev;<br />ino_t           st_ino;<br />mode_t          st_mode;<br />nlink_t         st_nlink;<br />uid_t           st_uid;<br />gid_t           st_gid;<br />dev_t           st_rdev;<br />off_t           st_size;<br />timestruc_t     st_atim;<br />timestruc_t     st_mtim;<br />timestruc_t     st_ctim;<br />blksize_t       st_blksize;<br />blkcnt_t        st_blocks;<br />char            st_fstype[_ST_FSTYPSZ];<br />};</p>
		<p>
				<span style="COLOR: #3366ff">
						<strong>fedora的struct stat定义：</strong>
				</span>
		</p>
		<p>struct stat<br />{<br />__dev_t st_dev;                     /* Device.  */<br />unsigned short int __pad1;<br />__ino_t st_ino;                     /* File serial number.  */<br />__mode_t st_mode;                   /* File mode.  */<br />__nlink_t st_nlink;                 /* Link count.  */<br />__uid_t st_uid;                     /* User ID of the file’s owner. */<br />__gid_t st_gid;                     /* Group ID of the file’s group.*/<br />__dev_t st_rdev;                    /* Device number, if device.  */<br />unsigned short int __pad2;<br />__off_t st_size;                    /* Size of file, in bytes.  */<br />__blksize_t st_blksize;             /* Optimal block size for I/O.  */<br />__blkcnt_t st_blocks;               /* Number 512-byte blocks allocated. */<br />struct timespec st_atim;            /* Time of last access.  */<br />struct timespec st_mtim;            /* Time of last modification.  */<br />struct timespec st_ctim;            /* Time of last status change.  */<br />unsigned long int __unused4;<br />unsigned long int __unused5;<br />};</p>
		<p>
				<strong>2</strong>
		</p>
		<p>大家一定注意到了，在上面列举域的时候，我在st_mode处使用了<span style="COLOR: #ff6600"><strong>黑体橘红色</strong></span>标识，原因在于这个域不像其他域那么容易使用，其他的域的值显而易见，而st_mode域是需要一些宏予以配合才能使用的。其实，通俗说，这些宏就是一些特定位置为1的二进制数的外号，我们使用它们和st_mode进行”&amp;”操作，从而就可以得到某些特定的信息。</p>
		<p>
				<strong>文件类型标志包括：</strong>
		</p>
		<p>S_IFBLK：文件是一个特殊的块设备</p>
		<p>S_IFDIR：文件是一个目录</p>
		<p>S_IFCHR：文件是一个特殊的字符设备</p>
		<p>S_IFIFO：文件是一个FIFO设备</p>
		<p>S_IFREG：文件是一个普通文件（REG即使regular啦）</p>
		<p>S_IFLNK：文件是一个符号链接</p>
		<p>
				<strong>其他模式标志包括：</strong>
		</p>
		<p>S_ISUID：文件设置了SUID位</p>
		<p>S_ISGID：文件设置了SGID位</p>
		<p>S_ISVTX：文件设置了sticky位</p>
		<p>
				<strong>用于解释st_mode标志的掩码包括：</strong>
		</p>
		<p>S_IFMT：文件类型</p>
		<p>S_IRWXU：属主的读/写/执行权限，可以分成S_IXUSR, S_IRUSR, S_IWUSR</p>
		<p>S_IRWXG：属组的读/写/执行权限，可以分成S_IXGRP, S_IRGRP, S_IWGRP</p>
		<p>S_IRWXO：其他用户的读/写/执行权限，可以分为S_IXOTH, S_IROTH, S_IWOTH</p>
		<p>
				<strong>还有一些用于帮助确定文件类型的宏定义，这些和上面的宏不一样，这些是带有参数的宏，类似与函数的使用方法：</strong>
		</p>
		<p>S_ISBLK：测试是否是特殊的块设备文件</p>
		<p>S_ISCHR：测试是否是特殊的字符设备文件</p>
		<p>S_ISDIR：测试是否是目录（我估计find . -type d的源代码实现中就用到了这个宏）</p>
		<p>S_ISFIFO：测试是否是FIFO设备</p>
		<p>S_ISREG：测试是否是普通文件</p>
		<p>S_ISLNK：测试是否是符号链接</p>
		<p>S_ISSOCK：测试是否是socket</p>
		<p>
				<strong>3</strong>
		</p>
		<p>我们已经学习完了struct stat和各种st_mode相关宏，现在就可以拿它们和stat系统调用相互配合工作了！</p>
		<p>int fstat(int filedes, struct stat *buf);</p>
		<p>int stat(const char *path, struct stat *buf);</p>
		<p>int lstat(const char *path, struct stat *buf);</p>
		<p>聪明人一眼就能看出来fstat的第一个参数是和另外两个不一样的，对！fstat区别于另外两个系统调用的地方在于，<font style="BACKGROUND-COLOR: #66ff00">fstat系统调用接受的是 一个“文件描述符”，而另外两个则直接接受“文件全路径”。文件描述符是需要我们用open系统调用后才能得到的，而文件全路经直接写就可以了。</font></p>
		<p>
				<font style="BACKGROUND-COLOR: #ff99ff">stat和lstat的区别：当文件是一个符号链接时，lstat返回的是该符号链接本身的信息；而stat返回的是该链接指向的文件的信息。（似乎有些晕吧，这样记，lstat比stat多了一个l，因此它是有本事处理符号链接文件的，因此当遇到符号链接文件时，lstat当然不会放过。而 stat系统调用没有这个本事，它只能对符号链接文件睁一只眼闭一只眼，直接去处理链接所指文件喽）</font>
		</p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/51411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-11-13 22:27 <a href="http://www.cnitblog.com/guopingleee/archive/2008/11/13/51411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用mmap()共享内存(转)</title><link>http://www.cnitblog.com/guopingleee/archive/2008/11/13/51396.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Thu, 13 Nov 2008 04:25:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/11/13/51396.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/51396.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/11/13/51396.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/51396.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/51396.html</trackback:ping><description><![CDATA[
		<h1>用mmap()共享内存</h1>
		<div id="article_header">
				<strong>rurutia</strong> posted @ 2007年04月27日 11:48PM in <a href="http://rurutia.is-programmer.com/categories/36/posts">编程笔记</a> with tags <a href="http://rurutia.is-programmer.com/tag/%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98">共享内存</a><a href="http://rurutia.is-programmer.com/tag/mmap">mmap</a></div>
		<small>
				<a class="down" title="下一篇文章" href="http://rurutia.is-programmer.com/posts/100.html">用python解析html</a>
		</small>
		<div id="article_body">
				<p>接口：</p>
				<pre>void *mmap( void *start, size_t length, int port, int flags, int fd, off_t offset)</pre>
				<p>正常返 回映射区的地址，出错返回-1。</p>
				<p>start 为映射区域的首地址，一般赋 值NULL通过系统自动分配。</p>
				<p>length 为区域大小。</p>
				<p>fd 为映射文件的文件描述符。</p>
				<p>offset 为映 射文件的偏移，也就是从文件的offset处开始映射。</p>
				<p>port : 映射 区域的属性值，可取PORT_EXEC, PORT_READ, PORT_WRITE, PORT_NONE，四个值，分别 是区域内可执行、可读、可写和不可访问。</p>
				<p>flags : 映射文件属 性值，可取 MAP_ANON, MAP_PRIVATE, MAP_SHARED，分别代表匿名映射，私有copy-on -write映射，和共享映射。</p>
				<p>MAP_ANON映射只能实现父子进程的内存共 享，因为只有父子进程有才有相同的映射后的地址空间，不同进程的内存共享需要用 MAP_SHARED通过映射文件来实现。</p>
				<p>值得一提的是，映射的初期并没有 真正分配内存，只有访问页面的时候，引发一个缺页异常，这时才真正分配内存。</p>
				<p>示例a.c和b.c，先建立一个文件sharefile，内容是”My name is Foo!”。</p>
				<p>----a.c----<br />#include &lt;stdio.h&gt;<br />#include &lt;unistd.h&gt;<br />#include &lt;sys/mman.h&gt;<br />#include &lt;sys/stat.h&gt;<br />#include &lt;fcntl.h&gt;<br /></p>
				<pre>int main()<br /><br /><br />{<br />   int fd;<br />   char *prt;<br />   char *msg="My name is Foo!";<br /><br /><br />   fd=open("sharefile",O_RDWR,00777);<br />   prt=(char*) mmap(NULL,strlen(msg)+1,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);<br />   close(fd);<br /><br />   memcpy(prt,msg,strlen(msg)+1);<br /><br />   printf("%s",prt);<br /><br />   sleep(10); /*等待b去修改共享内存内容。*/<br /><br />   printf("%s",prt);<br /><br />   munmap(prt,strlen(msg)+1);<br /><br />   return 0;<br />}</pre>
				<p>----b.c----</p>
				<pre>#include &lt;stdio.h&gt;<br />#include &lt;unistd.h&gt;<br />#include &lt;sys/mman.h&gt;<br />#include &lt;sys/stat.h&gt;<br />#include &lt;fcntl.h&gt;<br />int main()<br />{<br />   int fd;<br />   char *prt;<br /><br /><br />   char *msg="My name is Bar!";<br />   fd=open("sharefile",O_RDWR,00777);<br />   prt=(char*) mmap(NULL,strlen(msg)+1,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);<br />   close(fd);<br /><br />   memcpy(prt,msg,strlen(msg)+1);<br /><br />   munmap(prt,strlen(msg));<br /><br />   return 0;<br />}</pre>
				<p>运行./a 程序输出：</p>
				<pre>My name is Foo!</pre>
				<p>停止10s</p>
				<pre>My name is Foo!</pre>
				<p>
						<font color="#000000">先运行./a， 然后切换另一个控制台运行./b，切换回发现a的输出变为：</font>
				</p>
				<pre>
						<font color="#000000">My name is Foo!</font>
				</pre>
				<p>
						<font color="#000000">停止10s</font>
				</p>
				<pre>
						<font color="#000000">My name is Bar！</font>
				</pre>
				<p>
						<font color="#000000">可见，a内 存中的内</font>容被b修改了～最后的munmap函数会使得映射内存中的内容写回文件中，所以 文件中的内容也变成”My name is Bar!”。</p>
				<p>参考资料: 1. 《Computer Systems - A Programmer's Perspective》 2.《Linux Programming by Example》</p>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/51396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-11-13 12:25 <a href="http://www.cnitblog.com/guopingleee/archive/2008/11/13/51396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Makefile 实例子</title><link>http://www.cnitblog.com/guopingleee/archive/2008/11/03/51008.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 03 Nov 2008 08:07:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/11/03/51008.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/51008.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/11/03/51008.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/51008.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/51008.html</trackback:ping><description><![CDATA[不要为Makefil 困惑. 不会就去问了, 最好有人问, 没人找人, 我就是这样,<br />找了好多的群,  都是一个个加, 不懂就发言, 总有一个人回的, <br />多交这方面的朋友, 这样学得更快. <br />我的MSN: <a href="mailto:guoping@hotmail.com">guoping@hotmail.com</a><br />QQ: 529800142<br />希望交更多的朋友. 有错请指出.<br /><br /><br />2.Makefile的编写     <br />  假设我们有下面这样的一个程序,源代码如下:     <br />    <br />  /*   main.c   */     <br />  #include   "mytool1.h"     <br />  #include   "mytool2.h"     <br />    <br />  int   main(int   argc,char   **argv)     <br />  {     <br />  mytool1_print("hello");     <br />  mytool2_print("hello");     <br />  }     <br />    <br />  /*   mytool1.h   */     <br />  #ifndef   _MYTOOL_1_H     <br />  #define   _MYTOOL_1_H     <br />    <br />  void   mytool1_print(char   *print_str);     <br />    <br />  #endif     <br />    <br />  /*   mytool1.c   */     <br />  #include   "mytool1.h"     <br />  void   mytool1_print(char   *print_str)     <br />  {     <br />  printf("This   is   mytool1   print   %s\n",print_str);     <br />  }     <br />    <br />  /*   mytool2.h   */     <br />  #ifndef   _MYTOOL_2_H     <br />  #define   _MYTOOL_2_H     <br />    <br />  void   mytool2_print(char   *print_str);     <br />    <br />  #endif     <br />    <br />  /*   mytool2.c   */     <br />  #include   "mytool2.h"     <br />  void   mytool2_print(char   *print_str)     <br />  {     <br />  printf("This   is   mytool2   print   %s\n",print_str);     <br />  }     <br /><br />============================================<br />Makefile的文件是:  <br />[gping@localhost gp]$ vi Makefile(回车, 编辑器)<br />   <br />  #   这是上面那个程序的Makefile文件     <br />  main:main.o   mytool1.o   mytool2.o     <br /># 下面一行一定要加TAB键<br />            gcc   -o   main   main.o   mytool1.o   mytool2.o    <br />  main.o:main.c   mytool1.h   mytool2.h     <br />           gcc   -c   main.c     <br />  mytool1.o:mytool1.c   mytool1.h     <br />           gcc   -c   mytool1.c     <br />  mytool2.o:mytool2.c   mytool2.h     <br />           gcc   -c   mytool2.c     <br /><br /><br /><br />[gping@localhost gp]$ make <br />gcc   -c   main.c     <br />gcc   -o   main   main.o   mytool1.o   mytool2.o     <br />[gping@localhost gp]$ ./main <br />This   is   mytool1   print   hello<br />This   is   mytool2   print   hello<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />1.源程序的编译     <br />  在Linux下面,如果要编译一个C语言源程序,我们要使用GNU的gcc编译器.   下面我们以一个实例来说明如何使用gcc编译器.     <br />  假设我们有下面一个非常简单的源程序(hello.c):     <br />  int   main(int   argc,char   **argv)     <br />  {     <br />  printf("Hello   Linux\n");     <br />  }     <br />    <br />  要编译这个程序,我们只要在命令行下执行:     <br />  gcc   -o   hello   hello.c     <br />  gcc   编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程序的输出结果了.命令行中   gcc表示我们是用gcc来编译我们的源程序,-o   选项表示我们要求编译器给我们输出的可执行文件名为hello   而hello.c是我们的源程序文件.     <br />  gcc编译器有许多选项,一般来说我们只要知道其中的几个就够了.   -o选项我们已经知道了,表示我们要求输出的可执行文件名.   -c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件.   -g选项表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息.     <br />  知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了,如果你想要知道更多的选项,可以查看gcc的帮助文档,那里有着许多对其它选项的详细说明.     <br />  2.Makefile的编写     <br />  假设我们有下面这样的一个程序,源代码如下:     <br />    <br />  /*   main.c   */     <br />  #include   "mytool1.h"     <br />  #include   "mytool2.h"     <br />    <br />  int   main(int   argc,char   **argv)     <br />  {     <br />  mytool1_print("hello");     <br />  mytool2_print("hello");     <br />  }     <br />    <br />  /*   mytool1.h   */     <br />  #ifndef   _MYTOOL_1_H     <br />  #define   _MYTOOL_1_H     <br />    <br />  void   mytool1_print(char   *print_str);     <br />    <br />  #endif     <br />    <br />  /*   mytool1.c   */     <br />  #include   "mytool1.h"     <br />  void   mytool1_print(char   *print_str)     <br />  {     <br />  printf("This   is   mytool1   print   %s\n",print_str);     <br />  }     <br />    <br />  /*   mytool2.h   */     <br />  #ifndef   _MYTOOL_2_H     <br />  #define   _MYTOOL_2_H     <br />    <br />  void   mytool2_print(char   *print_str);     <br />    <br />  #endif     <br />    <br />  /*   mytool2.c   */     <br />  #include   "mytool2.h"     <br />  void   mytool2_print(char   *print_str)     <br />  {     <br />  printf("This   is   mytool2   print   %s\n",print_str);     <br />  }     <br />    <br />    <br />  当然由于这个程序是很短的我们可以这样来编译     <br />  gcc   -c   main.c     <br />  gcc   -c   mytool1.c     <br />  gcc   -c   mytool2.c     <br />  gcc   -o   main   main.o   mytool1.o   mytool2.o     <br />  这样的话我们也可以产生main程序,而且也不时很麻烦.但是如果我们考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新输入上面的命令?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我去完成不就可以了.是的对于这个程序来说,是可以起到作用的.但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译?     <br />  为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们只要执行以下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.--Makefile.对于上面的那个程序来说,可能的一个Makefile的文件是:     <br />  #   这是上面那个程序的Makefile文件     <br />  main:main.o   mytool1.o   mytool2.o     <br /># 下面一行一定要加TAB键<br />            gcc   -o   main   main.o   mytool1.o   mytool2.o    <br />  main.o:main.c   mytool1.h   mytool2.h     <br />           gcc   -c   main.c     <br />  mytool1.o:mytool1.c   mytool1.h     <br />           gcc   -c   mytool1.c     <br />  mytool2.o:mytool2.c   mytool2.h     <br />           gcc   -c   mytool2.c     <br />    <br />  有了这个Makefile文件,不过我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件她连理都不想去理的.     <br />  下面我们学习Makefile是如何编写的.     <br />  在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明.一般的格式是:     <br />  target:   components     <br />  TAB   rule     <br />    <br />  第一行表示的是依赖关系.第二行是规则.     <br />  比如说我们上面的那个Makefile文件的第二行     <br />  main:main.o   mytool1.o   mytool2.o     <br />  表示我们的目标(target)main的依赖对象(components)是main.o   mytool1.o   mytool2.o   当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令.就象我们的上面那个Makefile第三行所说的一样要执行   gcc   -o   main   main.o   mytool1.o   mytool2.o   注意规则一行中的TAB表示那里是一个TAB键     <br />  Makefile有三个非常有用的变量.分别是$@,$^,$&lt;代表的意义分别是:     <br />  $@--目标文件,$^--所有的依赖文件,$&lt;--第一个依赖文件.     <br />  如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为:     <br />  #   这是简化后的Makefile     <br />  main:main.o   mytool1.o   mytool2.o     <br />  gcc   -o   $@   $^     <br />  main.o:main.c   mytool1.h   mytool2.h     <br />  gcc   -c   $&lt;     <br />  mytool1.o:mytool1.c   mytool1.h     <br />  gcc   -c   $&lt;     <br />  mytool2.o:mytool2.c   mytool2.h     <br />  gcc   -c   $&lt;     <br />    <br />  经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点.这里我们学习一个Makefile的缺省规则     <br />  .c.o:     <br />  gcc   -c   $&lt;     <br />    <br />  这个规则表示所有的   .o文件都是依赖与相应的.c文件的.例如mytool.o依赖于mytool.c这样Makefile还可以变为:     <br />  #   这是再一次简化后的Makefile     <br />  main:main.o   mytool1.o   mytool2.o     <br />  gcc   -o   $@   $^     <br />  .c.o:     <br />  gcc   -c   $&lt;     <br />    <br />  好了,我们的Makefile   也差不多了,如果想知道更多的关于Makefile规则可以查看相应的文档.     <br />  3.程序库的链接     <br />  试着编译下面这个程序     <br />    <br />  /*   temp.c   */     <br />  #include     <br />    <br />  int   main(int   argc,char   **argv)     <br />  {     <br />  double   value;     <br />  printf("Value:%f\n",value);     <br />  }     <br />    <br />  这个程序相当简单,但是当我们用   gcc   -o   temp   temp.c   编译时会出现下面所示的错误.     <br />  /tmp/cc33Kydu.o:   In   function   `main:     <br />  /tmp/cc33Kydu.o(.text+0xe):   undefined   reference   to   `log     <br />  collect2:   ld   returned   1   exit   status     <br />    <br />  出现这个错误是因为编译器找不到log的具体实现.虽然我们包括了正确的头文件,但是我们在编译的时候还是要连接确定的库.在Linux下,为了使用数学函数,我们必须和数学库连接,为此我们要加入   -lm   选项.   gcc   -o   temp   temp.c   -lm这样才能够正确的编译.也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样的,对于一些常用的函数的实现,gcc编译器会自动去连接一些常用库,这样我们就没有必要自己去指定了.   有时候我们在编译程序的时候还要指定库的路径,这个时候我们要用到编译器的   -L选项指定路径.比如说我们有一个库在   /home/hoyt/mylib下,这样我们编译的时候还要加上   -L/home/hoyt/mylib.对于一些标准库来说,我们没有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib   /usr/lib   /usr/local/lib   在这三个路径下面的库,我们可以不指定路径.     <br />  还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢?很抱歉,对于这个问题我也不知道答案,我只有一个傻办法.首先,我到标准库路径下面去找看看有没有和我用的函数相关的库,我就这样找到了线程(thread)函数的库文件(libpthread.a).   当然,如果找不到,只有一个笨方法.比如我要找sin这个函数所在的库.   就只好用   nm   -o   /lib/*.so|grep   sin&gt;~/sin   命令,然后看~/sin文件,到那里面去找了.   在sin文件当中,我会找到这样的一行libm-2.1.2.so:00009fa0   W   sin   这样我就知道了sin在   libm-2.1.2.so库里面,我用   -lm选项就可以了(去掉前面的lib和后面的版本标志,就剩下m了所以是   -lm).   如果你知道怎么找,请赶快告诉我,我回非常感激的.谢谢!     <br />  4.程序的调试     <br />  我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了.     <br />  最常用的调试软件是gdb.如果你想在图形界面下调试程序,那么你现在可以选择xxgdb.记得要在编译的时候加入   -g选项.关于gdb的使用可以看gdb的帮助文件.由于我没有用过这个软件,所以我也不能够说出如何使用.   不过我不喜欢用gdb.跟踪一个程序是很烦的事情,我一般用在程序当中输出中间变量的值来调试程序的.当然你可以选择自己的办法,没有必要去学别人的.现在有了许多IDE环境,里面已经自己带了调试器了.你可以选择几个试一试找出自己喜欢的一个用.     <br />    <br />  5.头文件和系统求助     <br />  有时候我们只知道一个函数的大概形式,不记得确切的表达式,或者是不记得着函数在那个头文件进行了说明.这个时候我们可以求助系统.     <br />  比如说我们想知道fread这个函数的确切形式,我们只要执行   man   fread   系统就会输出着函数的详细解释的.和这个函数所在的头文件说明了.   如果我们要write这个函数的说明,当我们执行man   write时,输出的结果却不是我们所需要的.   因为我们要的是write这个函数的说明,可是出来的却是write这个命令的说明.为了得到write的函数说明我们要用   man   2   write.   2表示我们用的write这个函数是系统调用函数,还有一个我们常用的是3表示函数是C的库函数.     <br />  记住不管什么时候,man都是我们的最好助手.<img src ="http://www.cnitblog.com/guopingleee/aggbug/51008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-11-03 16:07 <a href="http://www.cnitblog.com/guopingleee/archive/2008/11/03/51008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux中/proc目录下文件详解</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50402.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 19 Oct 2008 05:14:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50402.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50402.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50402.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50402.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50402.html</trackback:ping><description><![CDATA[
		<h1>Linux中/proc目录下文件详解</h1>
		<div id="entrymeta">发表时间:2008-04-07 14:15:34    来源:网络整理    责任编辑:lkr    阅读数:
<script language="javascript" src="/plus/count.php?view=yes&amp;aid=3702&amp;mid=0"></script>
 348</div>
		<div class="clear">
		</div>
		<div id="entrybody">
				<div id="entryadbox">
				</div>
				<style><![CDATA[.Gfq620 { display:none; } ]]&gt;</style>
				<div>
						<font size="4">/proc文件系统下的多种文件提供的系统信息不是针对某个特定进程的，而是能够在整个系统范围的上下文中使用。可以使用的文件随系统配置的变化而变化。命令procinfo能够显示基于其中某些文件的多种系统信息。以下详细描述/proc下的文件。</font>
				</div>
				<div>
						<font size="4">--------------------------------------------------------------------------------<br />/proc/cmdline文件<br />这个文件给出了内核启动的命令行。它和用于进程的cmdline项非常相似。<br />--------------------------------------------------------------------------------<br />/proc/cpuinfo文件<br />这个文件提供了有关系统CPU的多种信息。这些信息是从内核里对CPU的测试代码中得到的。文件列出了CPU的普通型号（386，486，586，686等），以及能得到的更多特定信息（制造商，型号和版本）。文件还包含了以bogomips表示的处理器速度，而且如果检测到CPU的多种特性或者bug，文件还会包含相应的标志。这个文件的格式为：文件由多行构成，每行包括一个域名称，一个冒号和一个值。<br />--------------------------------------------------------------------------------<br />/proc/devices文件<br />这个文件列出字符和块设备的主设备号，以及分配到这些设备号的设备名称。 <span class="Gfq620">http://www.armforum.cn</span><br />--------------------------------------------------------------------------------<br />/proc/dma文件<br />这个文件列出由驱动程序保留的DMA通道和保留它们的驱动程序名称。casade项供用于把次DMA控制器从主控制器分出的DMA行所使用；这一行不能用于其它用途。<br />--------------------------------------------------------------------------------<br />/proc/filesystems文件<br />这个文件列出可供使用的文件系统类型，一种类型一行。虽然它们通常是编入内核的文件系统类型，但该文件还可以包含可加载的内核模块加入的其它文件系统类型。<br />--------------------------------------------------------------------------------<br />/proc/interrupts文件<br />这个文件的每一行都有一个保留的中断。每行中的域有：中断号，本行中断的发生次数，可能带有一个加号的域（SA_INTERRUPT标志设置），以及登记这个中断的驱动程序的名字。可以在安装新硬件前，像查看/proc/dma和/proc/ioports一样用cat命令手工查看手头的这个文件。这几个文件列出了当前投入使用的资源（但是不包括那些没有加载驱动程序的硬件所使用的资源）。<br />-------------------------------------------------------------------------------- <font color="#ffffff">字串8</font><br />/proc/ioports文件<br />这个文件列出了诸如磁盘驱动器，以太网卡和声卡设备等多种设备驱动程序登记的许多I/O端口范围。<br />--------------------------------------------------------------------------------<br />/proc/kcore文件<br />这个文件是系统的物理内存以core文件格式保存的文件。例如，GDB能用它考察内核的数据结构。它不是纯文本，而是/proc目录下为数不多的几个二进制格式的项之一。<br />-------------------------------------------------------------------------------<br />/proc/kmsg文件<br />这个文件用于检索用printk生成的内核消息。任何时刻只能有一个具有超级用户权限的进程可以读取这个文件。也可以用系统调用syslog检索这些消息。通常使用工具dmesg或守护进程klogd检索这些消息。<br />--------------------------------------------------------------------------------<br />/proc/ksyms文件<br />这个文件列出了已经登记的内核符号；这些符号给出了变量或函数的地址。每行给出一个符号的地址，符号名称以及登记这个符号的模块。程序ksyms,insmod和kmod使用这个文件。它还列出了正在运行的任务数，总任务数和最后分配的PID。<br />-------------------------------------------------------------------------------- <span class="Gfq620">字串4</span><br />/proc/loadavg文件<br />这个文件给出以几个不同的时间间隔计算的系统平均负载，这就如同uptime命令显示的结果那样。前三个数字是平均负载。这是通过计算过去1分钟，5分钟，15分钟里运行队列中的平均任务数得到的。随后是正在运行的任务数和总任务数。最后是上次使用的进程号。<br />--------------------------------------------------------------------------------<br />/proc/locks文件<br />这个文件包含在打开的文件上的加锁信息。文件中的每一行描述了特定文件和文档上的加锁信息以及对文件施加的锁的类型。内核也可以需要时对文件施加强制性锁。<br />--------------------------------------------------------------------------------<br />/proc/mdstat文件<br />这个文件包含了由md设备驱动程序控制的RAID设备信息。<br />--------------------------------------------------------------------------------<br />/proc/meminfo文件<br />这个文件给出了内存状态的信息。它显示出系统中空闲内存，已用物理内存和交换内存的总量。它还显示出内核使用的共享内存和缓冲区总量。这些信息的格式和free命令显示的结果类似。<br />-------------------------------------------------------------------------------- <font color="#ffffff">http://www.armforum.cn</font><br />/proc/misc文件<br />这个文件报告用内核函数misc_register登记的设备驱动程序。<br />--------------------------------------------------------------------------------<br />/proc/modules文件<br />这个文件给出可加载内核模块的信息。lsmod程序用这些信息显示有关模块的名称，大小，使用数目方面的信息。<br />--------------------------------------------------------------------------------<br />/proc/mounts文件<br />这个文件以/etc/mtab文件的格式给出当前系统所安装的文件系统信息。这个文件也能反映出任何手工安装从而在/etc/mtab文件中没有包含的文件系统。<br />--------------------------------------------------------------------------------<br />/proc/pci文件<br />这个文件给出PCI设备的信息。用它可以方便地诊断PCI问题。你可以从这个文件中检索到的信息包括诸如IDE接口或USB控制器这样的设备，总线，设备和功能编号，设备延迟以及IRQ编号。<br />--------------------------------------------------------------------------------<br />/proc/stat文件 <br />这个文件包含的信息有CPU利用率，磁盘，内存页，内存对换，全部中断，接触开关以及赏赐自举时间（自1970年1月1日起的秒数）。 <font color="#ffffff">http://www.armforum.cn</font><br />--------------------------------------------------------------------------------<br />/proc/uptime文件<br />这个文件给出自从上次系统自举以来的秒数，以及其中有多少秒处于空闲。这主要供uptime程序使用。比较这两个数字能够告诉你长期来看CPU周期浪费的比例。<br />--------------------------------------------------------------------------------<br />/proc/version文件<br />这个文件只有一行内容，说明正在运行的内核版本。可以用标准的编程方法进行分析获得所需的系统信息。<br />--------------------------------------------------------------------------------<br />/proc/net子目录<br />此目录下的文件描述或修改了联网代码的行为。可以通过使用arp,netstat,route和ipfwadm命令设置或查询这些特殊文件中的许多文件。<br />--------------------------------------------------------------------------------<br />以下摘要介绍此目录下文件的功能：<br />arp<br />转储每个网络接口的arp表中dev包的统计</font>
				</div>
				<div>
						<font size="4">dev<br />来自网络设备的统计</font>
				</div>
				<div>
						<font size="4">dev_mcast<br />列出二层（数据链路层）多播组</font>
				</div>
				<div>
						<font size="4">igmp 
<div class="Gfq620">字串5</div><br />加入的IGMP多播组</font>
				</div>
				<div>
						<font size="4">netlink<br />netlink套接口的信息</font>
				</div>
				<div>
						<font size="4">netstat<br />网络流量的多种统计。第一行是信息头，带有每个变量的名称。接下来的一行保存相应变量的值</font>
				</div>
				<div>
						<font size="4">raw<br />原始套接口的套接口表</font>
				</div>
				<div>
						<font size="4">route<br />静态路由表</font>
				</div>
				<div>
						<font size="4">rpc<br />包含RPC信息的目录</font>
				</div>
				<div>
						<font size="4">rt_cache<br />路由缓冲</font>
				</div>
				<div>
						<font size="4">snmp<br />snmp agent的ip/icmp/tcp/udp协议统计；各行交替给出字段名和值</font>
				</div>
				<div>
						<font size="4">sockstat<br />列出使用的tcp/udp/raw/pac/syc_cookies的数量</font>
				</div>
				<div>
						<font size="4">tcp<br />TCP连接的套接口</font>
				</div>
				<div>
						<font size="4">udp<br />UDP连接的套接口表</font>
				</div>
				<div>
						<font size="4">unix<br />UNIX域套接口的套接口表 <br />--------------------------------------------------------------------------------<br />示例：<br />[root@localhost /]# cat /proc/net/route<br />Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT 
<p class="Gfq620">字串8</p><br />eth0 0035C2DA 00000000 0001 0 0 0 80FFFFF0<br />eth0 0000FEA9 00000000 0001 0 0 0 0000FFF0<br />eth0 00000000 0135C2DA 0003 0 0 0 00000000 <br />--------------------------------------------------------------------------------<br />[root@localhost /]# cat /proc/net/tcp<br />sl local_address rem_address st tx_queue rx_queue tr tm-&gt;when retrnsmt uid timeout inode<br />0: 00000000:8000 00000000:0000 0A 00000000:00000000 00:00000000 00000000 29 0 9525 1 0dde7500 3000 0 0 2 -1<br />1: 00000000:006F 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 9484 1 0dde79e0 3000 0 0 2 -1<br />2: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 10049 1 0a8e3a00 3000 0 0 2 -1<br />3: 0100007F:14D7 00000000:0000 0A 00000000:00000000 00:00000000 00000000 99 0 9847 1 0dde7020 3000 0 0 2 -1<br />4: 0100007F:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 10286 1 0a8e3520 3000 0 0 2 -1 <br />--------------------------------------------------------------------------------<br />[root@localhost /]# cat /proc/net/arp 
<p class="Gfq620">字串5</p><br />IP address HW type Flags HW address Mask Device<br />218.194.53.1 0x1 0x2 00:0D:BC:78:07:3F * eth0 <br />--------------------------------------------------------------------------------<br />[root@localhost /]# cat /proc/net/udp<br />sl local_address rem_address st tx_queue rx_queue tr tm-&gt;when retrnsmt uid timeout inode<br />0: 00000000:8000 00000000:0000 07 00000000:00000000 00:00000000 00000000 29 0 9520 2 0b4ef7c0<br />105: 00000000:14E9 00000000:0000 07 00000000:00000000 00:00000000 00000000 99 0 10284 2 0b4ef040<br />111: 00000000:006F 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 9483 2 0b4efcc0<br />116: 00000000:02F4 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 9511 2 0b4efa40<br />119: 00000000:0277 00000000:0000 07 00000000:00000000 00:00000000 00000000 0 0 10050 2 0b4ef2c0</font>
				</div>
				<div>
						<font size="4">--------------------------------------------------------------------------------<br />/proc/scsi子目录<br />此目录下包含一个列出了所有检测到的SCSI设备的文件，并且为每种控制器驱动程序提供一个目录，在这个目录下又为已安装的此种控制器的每个实例提供一个子目录。 
<p class="Gfq620">M开发论坛</p><br />--------------------------------------------------------------------------------<br />/proc/sys子目录<br />在此目录下有许多子目录。此目录中的许多项都可以用来调整系统的性能。这个目录包含信息太多，无法介绍全部。只在示例中展示目录下的一些文件。<br />--------------------------------------------------------------------------------<br />[root@localhost ~]# ls /proc/sys/fs<br />aio-max-nr dentry-state file-nr lease-break-time overflowgid<br />aio-nr dir-notify-enable inode-nr leases-enable overflowuid<br />binfmt_misc file-max inode-state mqueue quota <br />--------------------------------------------------------------------------------<br />[root@localhost ~]# ls /proc/sys/kernel<br />acct hotplug panic sem<br />cad_pid modprobe panic_on_oops shmall<br />cap-bound msgmax pid_max shmmax<br />core_pattern msgmnb print-fatal-signals shmmni<br />core_uses_pid msgmni printk sysrq<br />ctrl-alt-del ngroups_max printk_ratelimit tainted<br />domainname osrelease printk_ratelimit_burst threads-max<br />exec-shield ostype pty vdso <span class="Gfq620">字串5</span><br />exec-shield-randomize overflowgid random version<br />hostname overflowuid real-root-dev <br />--------------------------------------------------------------------------------<br />[root@localhost ~]# ls /proc/sys/net<br />core ethernet ipv4 ipv6 unix <br />--------------------------------------------------------------------------------</font>
				</div>
				<div>
						<font size="4">[root@localhost sys]# ls /proc/sys/vm<br />block_dump laptop_mode nr_pdflush_threads<br />dirty_background_ratio legacy_va_layout overcommit_memory<br />dirty_expire_centisecs lower_zone_protection overcommit_ratio<br />dirty_ratio max_map_count page-cluster<br />dirty_writeback_centisecs min_free_kbytes swappiness<br />hugetlb_shm_group nr_hugepages vfs_cache_pressure <br />--------------------------------------------------------------------------------</font>
				</div>
				<div>
						<font size="4">[root@localhost sys]# ls /proc/sys/net/ipv4<br />conf tcp_fack<br />icmp_echo_ignore_all tcp_fin_timeout<br />icmp_echo_ignore_broadcasts tcp_frto<br />icmp_ignore_bogus_error_responses tcp_keepalive_intvl <font color="#ffffff">http://www.armforum.cn</font><br />icmp_ratelimit tcp_keepalive_probes<br />icmp_ratemask tcp_keepalive_time<br />igmp_max_memberships tcp_low_latency<br />igmp_max_msf tcp_max_orphans<br />inet_peer_gc_maxtime tcp_max_syn_backlog<br />inet_peer_gc_mintime tcp_max_tw_buckets<br />inet_peer_maxttl tcp_mem<br />inet_peer_minttl tcp_moderate_rcvbuf<br />inet_peer_threshold tcp_no_metrics_save<br />ip_autoconfig tcp_orphan_retries<br />ip_conntrack_max tcp_reordering<br />ip_default_ttl tcp_retrans_collapse<br />ip_dynaddr tcp_retries1<br />ip_forward tcp_retries2<br />ipfrag_high_thresh tcp_rfc1337<br />ipfrag_low_thresh tcp_rmem<br />ipfrag_secret_interval tcp_sack<br />ipfrag_time tcp_stdurg<br />ip_local_port_range tcp_synack_retries<br />ip_nonlocal_bind tcp_syncookies<br />ip_no_pmtu_disc tcp_syn_retries<br />neigh tcp_timestamps<br />netfilter tcp_tso_win_divisor<br />route tcp_tw_recycle<br />tcp_abort_on_overflow tcp_tw_reuse<br />tcp_adv_win_scale tcp_vegas_alpha<br />tcp_app_win tcp_vegas_beta<br />tcp_bic tcp_vegas_cong_avoid<br />tcp_bic_fast_convergence tcp_vegas_gamma <font color="#ffffff">字串8</font><br />tcp_bic_low_window tcp_westwood<br />tcp_dsack tcp_window_scaling<br />tcp_ecn tcp_wmem <br />--------------------------------------------------------------------------------</font>
				</div>
				<div>
						<font size="4">[root@localhost sys]# cat /proc/sys/kernel/shmall<br />2097152 <br />--------------------------------------------------------------------------------<br />[root@localhost sys]# cat /proc/sys/kernel/osrelease<br />2.6.9-1.667<br />--------------------------------------------------------------------------------<br />总结：<br />/proc文件系统包含了大量的有关当前系统状态的信息。proc的手册页中也有对这些文件的解释文档。把文件和分析这些文件的工具产生的输出进行比较能够更加清晰地了解这些文件</font>
				</div>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50402.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-19 13:14 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/19/50402.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ARM 开发软件及实用工具介绍</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50401.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 19 Oct 2008 05:05:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50401.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50401.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50401.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50401.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50401.html</trackback:ping><description><![CDATA[
		<h1>ARM 开发软件及实用工具介绍</h1>
		<div id="entrymeta">发表时间:2008-07-06 13:48:10 来源:网络整理 责任编辑:lkr 阅读数:
<script language="javascript" src="/plus/count.php?view=yes&amp;aid=3788&amp;mid=0"></script>
 1329</div>
		<div class="clear">
		</div>
		<div id="entrybody">
				<div id="entryadbox">
				</div>
				<style><![CDATA[.Rhv372 { display:none; } ]]&gt;</style>
				<p>
						<font size="4">1、ADS1.2<br />    ADS是ARM公司的集成开发环境软件，他的功能非常强大。他的前身是SDT，SDT是ARM公司几年前的开发环境软件，目前SDT早已经不再升级。ADS包括了四个模块分别是：SIMULATOR；C 编译器；实时调试器；应用函数库。<br />ADS 的编译器调试器较SDT都有了非常大的改观， ADS1.2提供完整的WINDOWS界面开发环境。C编译器效率极高，支持c 以及c++，使工程师可以很方便的使用C语言进行开发。提供软件模拟仿真功能，使没有Emulators的学习者也能够熟悉ARM的指令系统。配合FFT -ICE使用，ADS1.2提供强大的实时调试跟踪功能,片内运行情况尽在掌握。ADS1.2需要硬件支持才能发挥强大功能。目前支持的硬件调试器有 Multi-ICE以及兼容Multi-ICE的调试工具如FFT-ICE。而简易下载电缆不能支持ADS1.2<br />版本：ADS1.2<br />软件大小：130M </font>
				</p>
				<div class="Rhv372">ARM</div>
				<p>
				</p>
				<p>
						<font size="4">2、ARM REALVIEW DEVELOPER SUITE<br />    RealView Developer Suite工具是ARM公司是推出的新一代ARM集成开发工具。支持所有ARM 系列核，并与众多第三方实时操作系统及工具商合作简化开发流程。开发工具包含以下组件：</font>
				</p>
				<p class="Rhv372">字串5</p>
				<p>
				</p>
				<p>
						<font size="4"> 完全优化的ISO C/C++编译器 <br /> C++ 标准模板库 <br /> 强大的宏编译器 <br /> 支持代码和数据复杂存储器布局的连接器 <br /> 可选 GUI调试器 <br /> 基于命令行的符号调试器(armsd) <br /> 指令集仿真器 <br /> 生成无格式二进制工具、Intel 32位和Motorola 32位ROM映像代码的指令集模拟工具 <br /> 库创建工具 <br /> 内容丰富的在线文档<br />版本：ARM.RealView.Developer2.2<br />软件大小：500M  <br />3、IAR EWARM<br />    Embedded Workbench for ARM 是IAR Systems 公司为ARM 微处理器开发的一个集成开发环境(下面简称IAR EWARM)。比较其他的ARM 开发环境，IAR EWARM 具有入门容易、使用方便和代码紧凑等特点。</font>
				</p>
				<p class="Rhv372">字串5</p>
				<p>
				</p>
				<p>
						<font size="4">    IAR Systems 公司目前推出的最新版本是IAR Embedded Workbench for ARM version 4.30。这里提供的是32k 代码限制、但没有时间限制的Kickstart版。</font>
						<font color="#ffffff">http://www.armforum.cn</font>
				</p>
				<p>
						<font size="4">    EWARM 中包含一个全软件的模拟程序(simulator)。用户不需要任何硬件支持就可以模拟各种ARM 内核、外部设备甚至中断的软件运行环境。从中可以了解和评估IAR EWARM 的功能和使用方法。</font>
						<font color="#ffffff">ARM</font>
				</p>
				<p>
						<font size="4">IAR EWARM 的主要特点如下：</font>
						<font color="#ffffff">字串4</font>
				</p>
				<p>
						<font size="4">高度优化的IAR ARM C/C++ Compiler <br />IAR ARM Assembler <br />一个通用的IAR XLINK Linker <br />IAR XAR 和XLIB 建库程序和IAR DLIB C/C++运行库 <br />功能强大的编辑器 <br />项目管理器 <br />命令行实用程序 <br />IAR C-SPY 调试器(先进的高级语言调试器 <br />版本：IAR EWARM 4.40a<br />软件大小：93M </font>
				</p>
				<p class="Rhv372">字串4</p>
				<p>
				</p>
				<p>
						<font size="4">4、KEIL ARM-MDKARM   <br />  Keil uVision调试器可以帮助用户准确地调试ARM器件的片内外围功能(I2C、 CAN、UART、SPI、中断、I/O口、A/D转换器、D/A转换器和PWM模块等功能)。ULINK USB-JTAG转换器将PC机的USB端口与用户的目标硬件相连(通过JTAG或OCD)，使用户可在目标硬件上调试代码。通过使用Keil uVision IDE/调试器和ULINK USB-JTAG转换器，用户可以很方便地编辑、下载和在实际的目标硬件上测试嵌入的程序。</font>
				</p>
				<p class="Rhv372">ARM开发论坛</p>
				<p>
				</p>
				<p>
						<font size="4"> 支持Philips、Samsung、 Atmel、 Analog Devices、 Sharp、 ST等众多厂商ARM7内核的ARM微控制器。 <br /> 高效工程管理的uVision3集成开发环境 <br /> Project/Target/Group/File的重叠管理模式，并可逐级设置； <br /> 高度智能彩色语法显示； <br /> 支持编辑状态的断点设置,并在仿真状态下有效。 <br /> 高速ARM指令/外设模拟器 <br /> 高效模拟算法缩短大型软件的模拟时间； <br /> 软件模拟进程中允许建立外部输入信号； <br /> 独特的工具窗口，可快速查看寄存器和方便配置外设； <br /> 支持C调试描述语言，可建立与实际硬件高度吻合的仿真平台； <br /> 支持简单/条件/逻辑表达式/存储区读写/地址范围等断点。 <br />多种流行编译工具选择 <br /> Keil高效率C编译器； <br /> ARM公司的ADS/RealView 编译器； <br /> GNU GCC 编译器； <br /> 后续厂商的编译器。<br />版本: MDKARM V3.10A<br />软件大小：53M  <br />5、WINARM (GCCARM)<br />  WINARM  是一个免费的开发工具。<br />  里面除了包含 C/C++ 编译器——GCC，汇编、连接器——Binutils，调试器——GDB等工具，也包括了通过 GDB 使用 Wiggler JTAG 的软件——OCDRemote。所以，所需要的工具都包括在了这个 WinARM 发行版中，就可以比较省心了。</font>
				</p>
				<p class="Rhv372">字串8</p>
				<p>
				</p>
				<p>
						<font size="4">　　软件大小：90M</font>
				</p>
				<div class="Rhv372">http://www.armforum.cn</div>
				<p>
				</p>
				<p>
						<font size="4">二、相关开发工具介绍</font>
						<span class="Rhv372">http://www.armforum.cn</span>
				</p>
				<p>
						<font size="4">１、H-JTAG调试代理<br />    H-JTAG是一个免费的ARM调试代理，程序没有任何限制，希望能给ARM的爱好者提供一个简单实用的学习工具。欢迎访问作者的BLOG: </font>
						<a href="http://twentyone.blogchina.comblog/">
								<font color="#002c99" size="4">http://twentyone.blogchina.comblog</font>
						</a>
						<font size="4">提供了安装程序的下载，同时，也提供了常见的Q&amp;A.</font>
						<span class="Rhv372">ARM</span>
				</p>
				<p>
						<font size="4"> 支持ARM7/ARM9,支持自动检测和手动指定内核 <br /> 使用RDI接口，支持SDT,ADS,REALVIEW和IAR <br /> 支持ADS1.2和SDT2.51和RREAL VIEW <br /> 支持个硬件断点或者数量不限的软件断点 <br /> 支持ARM/THUMB模式 <br /> 支持LITTLEENDIAN &amp; BIGENDIAN <br /> 支持SEMIHOSTING <br /> 支持WIGGLER SDTJTAG和自定义接口 <br />２、LPC2000系列ISP工具<br />   a、飞利普官方网站下载工具<br />   b、</font>
				</p>
				<p class="Rhv372">M开发论坛</p>
				<p>
				</p>
				<p>
						<font size="4">３、Macraigor Systems Wiggler 调试工具</font>
				</p>
				<div class="Rhv372">http://www.armforum.cn</div>
				<p>
				</p>
				<p>
						<font size="4">４、J-LINK<br />    IAR公司的J-LINK是一款小巧的ARM JTAG硬件调试器，它是通过USB口与PC机相连。IAR的J-LINK与该公司的嵌入式开发平台紧密结合，且完全支持即插即用。</font>
						<span class="Rhv372">ARM</span>
				</p>
				<p>
						<font size="4">主要特征:</font>
				</p>
				<div class="Rhv372">字串8</div>
				<p>
				</p>
				<p>
						<font size="4">支持所有ARM7和ARM9 <br />下载速度高达600KB/sec <br /> 无需电源供电,可直接通过USB取电 <br />JTAG速度是8MHz <br />自动辨速 <br />监控所有的JTAG管脚信号,测量电压 <br />20pin标准JTAG连接器 <br />配带USB口和20pin插槽 <br />支持Windows 2000 和Windows XP <br />更强的几点：<br />1、支持ADS,KEIL,IAR,WINARM,RV等几乎所有开发环境；并且可以和IAR无缝连接<br />2、支持FLASH软件断点，可以设置2个以上断点（无限个断点），极大的提高调试效率；<br />3、带J-Link TCP/IP server，允许通过TCP/ IP 网络使用J-Link<br />4、支持几乎所有ARM7,ARM9，暂时不支持XSCALE；<br />* ARM7TDMI（Rev 1）<br />* ARM7TDMI（Rev 3）<br />* ARM7TDMI-S（Rev 4）<br />* ARM720T<br />* ARM920T<br />* ARM926EJ-S<br />* ARM946E-S</font>
				</p>
				<div class="Rhv372">ARM</div>
				<p>
				</p>
				<p>
						<font size="4">6、U-LINK<br />    ARM7 TDMI结构的Keil开发套件采用最新设计的超豪华uVision3集成开发环境，内嵌C编译器/汇编器/工程管理器/调试器等功能功能模块，是一款稳定/可靠/高效的开发工具，适用于不同层次的的用户，完全满足从专业的应用开发工程师到初学嵌入式软件开发的学生的所有使用要求。类似于8051的智能平台将大幅度缩短您的开发周期，各大半导体厂商的所有ARM型号将逐一得到全面支持。</font>
				</p>
				<div class="Rhv372">ARM</div>
				<p>
				</p>
				<p>
						<font size="4">    Keil uVision调试器可以帮助用户准确地调试ARM器件的片内外围功能(I2C、 CAN、UART、SPI、中断、I/O口、A/D转换器、D/A转换器和PWM模块等功能)。ULINK USB-JTAG转换器将PC机的USB端口与用户的目标硬件相连(通过JTAG或OCD)，使用户可在目标硬件上调试代码。通过使用Keil uVision IDE/调试器和ULINK USB-JTAG转换器，用户可以很方便地编辑、下载和在实际的目标硬件上测试嵌入的程序。</font>
				</p>
				<p class="Rhv372">http://www.armforum.cn</p>
				<p>
				</p>
				<p>
						<font size="4">支持Philips、Samsung、 Atmel、 Analog Devices、 Sharp、 ST等众多厂商ARM7内核的ARM微控制器。 <br />高效工程管理的uVision3集成开发环境 <br /> Project/Target/Group/File的重叠管理模式，并可逐级设置； <br /> 高度智能彩色语法显示； <br />支持编辑状态的断点设置,并在仿真状态下有效。 <br />高速ARM指令/外设模拟器 <br />高效模拟算法缩短大型软件的模拟时间； <br />软件模拟进程中允许建立外部输入信号； <br />独特的工具窗口，可快速查看寄存器和方便配置外设； <br />支持C调试描述语言，可建立与实际硬件高度吻合的仿真平台； <br />支持简单/条件/逻辑表达式/存储区读写/地址范围等断点。 <br />多种流行编译工具选择<br /> Keil高效率C编译器；<br /> ARM公司的ADS/RealView 编译器；<br /> GNU GCC 编译器；<br /> 后续厂商的编译器。 <br />JTAG仿真器ULINK<br />* USB通讯接口高速下载用户代码；<br />* 存储区域/寄存器查看；<br />* 快速单步程序运行；<br />* 多种程序断点；<br />* 片内Flash编程 。</font>
				</p>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-19 13:05 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/19/50401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>嵌入式技术行业知识</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50400.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 19 Oct 2008 05:02:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50400.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50400.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50400.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50400.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50400.html</trackback:ping><description><![CDATA[
		<h1>嵌入式技术行业知识</h1>
		<div id="entrymeta">发表时间:2008-09-26 07:25:52 来源: 责任编辑:阿壬 阅读数:
<script language="javascript" src="/plus/count.php?view=yes&amp;aid=3901&amp;mid=0"></script>
 267</div>
		<div class="clear">
		</div>
		<div id="entrybody">
				<div id="entryadbox">
				</div>
				<style><![CDATA[.Pbb659 { display:none; } ]]&gt;</style>
				<p>
						<font size="4">
								<br />1 什么是嵌入式系统<br />嵌入式系统是以应用为中心，以计算机技术为基础，且软硬件可裁减，适应应用系统对功能、可靠性、成本、体积、功耗有严格要求的专用计算机系统。<br />它一般由以下几部分组成:􀂄<br />1 嵌入式微处理器<br />2 外围硬件设备<br />3 嵌入式操作系统<br />4 特定的应用程序<br />●  嵌入式系统的特点<br />特点：<br />􀂄应用的特定性和广泛性<br />􀂄技术、知识、资金的密集性<br />􀂄高效性<br />􀂄较长的生命周期<br />􀂄高可靠性<br />􀂄软硬一体，软件为主<br />􀂄无自举开发能力<br />1 嵌入式技术的前景<br />1﹑2004年，全球嵌入式系统产品的产值已达2000亿美元，国内嵌入式软件的产值也达到600亿人民币。<br />2﹑2003年全球嵌入式软件市场规模达到346亿美元， 2003年中国市场规模达到188亿元，预计到2006年嵌入式软件市场规模将突破400亿元大关，2003-2006年均复合增长率将达到30%。</font>
						<span class="Pbb659">M开发论坛</span>
				</p>
				<p>
						<font size="4">1 嵌入式系统的应用领域<br />    按照行业细分, 嵌入式产品主要分布在消费类电子、通信、医疗安全等行业。例如:汽车、通讯、信息电器、医疗、军事﹑工控﹑交通管理等.<br />2 嵌入式系统的相关产品<br /> 1. 网络设备2. :交换机、路由器,MODEM􀂄<br /> 3. 消费电子:手机、MP3、PDA 、可视电话、机顶盒（Set Top Box）、数字电视、数码照相机、数码摄像机(DV)、信息家电􀂄<br /> 4. 办公设备5. :打印机、传真机、扫描仪􀂄<br /> 6. 汽车电子:ABS(防死锁刹车系统)、供油喷射控制系统􀂄<br /> 7. 工业控制:各种自动控制设备8. (如: 数控设备9. 或仪表、家电控制系统、医疗仪器、航天航空设备10. <br />3 嵌入式人才需求<br />1﹑业内人士认为，通信领域(3G)至少需要40万嵌入式人才，电信业嵌入式人才的需求将会在今后一段时间内继续上扬。<br />2﹑业内人士认为，(3G)目前至少出现30-50万的人才缺口，其中嵌入式15 万，移动增值可能35万。今年3 月，据英才网指数统计显示，计算机/ 信息服务共提供82069 个空缺职位，占当月所有空缺职位总数的30.37%。排名第一。嵌入式工程师行情不断走高，多家IT公司均在招募嵌入式研发工程师、嵌入式技术支持工程师。随着车载电子应用、手持娱乐终端在国内的普及，今年以来国内外企业纷纷加大了对嵌入式业务的投入，相关人才需求也逐渐加大。 
<p class="Pbb659">ARM</p><br />4 对嵌入式人才的要求<br />1﹑必须具备C语言编程经验、嵌入式操作系统（嵌入式Linux）经验、内核裁剪经验、驱动程序开发经验。<br />2﹑高级嵌入式软件开发工程师相关职位要求是：<br />（1）﹑有丰富的嵌入式多任务软件系统分析和设计能力，能独立完成项目系统方案，解决系统故障和问题；<br />（2）﹑精通C语言应用开发，有良好的编程习惯和风格，程序稳定可靠；<br />（3）、良好的文档编写能力和习惯，能够编写规范的概要和详细设计文档；<br />(4) ﹑熟悉项目管理流程。特别指出，良好的英文阅读能力及较强的学习能力是从事这一领域工作的基础，而熟悉Linux是该职位录用的优先指标。<br />5 嵌入式人才的收入<br />1﹑初入门的嵌入式开发人员年薪一般都能达到4-7万元.<br />今年就业高校应届毕业生嵌入式研发岗位薪水：本科：4—10万，硕士：6—17万<br />2﹑有3年以上经验的人员年薪都在10万元以上.<br />3﹑有10年工作经验的高级嵌入式工程师年薪在30万元左右。<br />不仅薪水不菲，嵌入式人才的工作环境与发展前景也有优势。<br />●   主流的嵌入式微处理器<br /> ARM/Strong (ARM公司)􀂄<br /> PowerPC (MOTOROL公司) <font color="#ffffff">字串4</font><br />1. PowerPC架构的特点是可伸缩性好，2. 方便灵活。PowerPC处理器品种很多，3. 既有通用的处理器，4. 又有嵌入式控制器和内核，5. 应用范围非常广泛，6. 从高端的工作站、服7. 务器到桌面计算机系统，8. 从消费类电子产品到大型通信设备，9. 无所不10. 包。<br />11. 处理器芯片主要型号是PowerPC 750，12. 它于1997年研制成功，13. 最高的工作频率可以达到500MHz，14. 采用先进的铜线技术。该处理器有许多品种，15. 以便适合各种不同16. 的系统。包括IBM小型机、苹果电脑和其他系统。<br />17. 嵌入式的PowerPC 405（主频最高为266MHz）和PowerPC 440（主频最高为550MHz）处理器内核可以用于各种SoC设计上，18. 在电信、金融和其他许多行业具有广泛的应用。<br /> 68000 (MOTOROL公司)􀂄<br /> MIPS(MIPS公司)<br />1. MIPS技术公司是一家设计制造高性能、高档次及嵌入式32位和64位处理器的厂商。在RISC处理器方面占有重要地位。<br />2. MIPS的意思是无内锁流水段微处理器（Microprocessor without interlocked piped stages），3. 最早是在80年代初期由美国斯坦福大学Hennessy教授领导的研究小组研制出来的。 
<p class="Pbb659">字串8</p><br />4. 1986年推出R2000处理器，5. 1988年推出R3000处理器，6. 1991年推出第一款64位商用微处理器R4000。之后，7. 又陆续推出R8000（于1994年）、R10000（于1996年）和R12000（于1997年）等型号。之后，8. MIPS公司的战略发生变化<br />6 几种主流的嵌入式操作系统<br /> 11. Vxworks: 美国WindRiver公司于1983年开发，12. 具有可靠、实时、可裁减特性。<br /> 13. Windows Embedded:支持具有丰富应用程序和服14. 务的32位嵌入式系统。主要系列：Windows CE3.0, Windows NT Embedded 4.0和带有Server Appliance Kit的Windows 2000<br /> 15. Palm OS: Com公司产品，16. 在PDA市场占据很大份额，17. 具有开放的操作系统应用程序接口(API)，18. 可让用户灵活方便地定制操作系统。<br /> 19. 嵌入式Linux：近两年来，20. Linux在嵌入式领域异军突起，21. 他的独特性，22. 使其作为开发嵌入式产品的操作系统具备23. 巨大的潜力。Linux具有一些独特的优势：层次结构及内核完全开放；强大的网络支持功能；具备24. 一整套工具链；广泛的硬件支持特性。<br />7 成都做嵌入式产品的代表企业 
<div class="Pbb659">字串4</div><br /> 25. 上海贝尔阿尔卡特(成都研发基地)<br />公司地址:四川省成都市高新区天府大道天府软件园B8 8层 <br />26. 诺基亚(成都研发基地)<br />在成都设立的研发中心已于日前正式迁入位于成都高新技术开发区的天府软件园.<br />27.  摩托罗拉中国软件研发中心 <br /> 摩托罗拉中国软件研发中心（成都）于2001年1月建立，是摩托罗拉继北京、南京之后设立的第三个软件研发中心，参与全球大、中型软件项目的设计与开发、软件产品和服务遍及摩托罗拉的各个业务领域，并将逐步扩建为摩托罗拉全球重点软件中心。 <br />28. 爱立信成都技术研发中心 <br /> 2004年4月，爱立信在成都设立全球性技术研发中心，初期的主要任务是为中国及全球市场开发基于GSM、CDMA及WCDMA等移动标准的无线基站产品，该研发中心于11月8日被正式定名为爱立信无线技术（成都）有限公司，落户成都高新区，并成立爱立信（中国）西部区总部。公司宣布还即将在成都设立CDMA应用开发中心。 <br />29. 成都微软技术中心<br />是微软公司在中国成立的首家合作技术机构，于2004年4月落户成都高新区，致力于建设具有国际水平的信息安全暨应用软件平台的研发、开发、系统测试、服务及人才培养，构建了跨国IT公司参与成都软件产业公共平台建设的新模式。 
<div class="Pbb659">ARM</div><br />30.  凌成科技（成都）有限公司<br />凌成科技（成都）有限公司系消费类集成电路设计公司，座落于成都高新西区创新中心，拥有1200多平方米的科研场地，现有员工120人。公司研发机构分为四大中心：系统产品中心、系统软件中心、芯片设计中心和数位内容中心，专业从事嵌入式系统硬件产品、系统软件产品、数字游戏产品和多媒体芯片产品的设计与开发，其终端产品面向全球市场。 <br />31.  联想研究院成都分院 <br /> 联想集团继北京、上海研究分院后成立的全国第三个研发基地--联想研究院成都分院于2004年11月30日落户高新区，致力于"高可靠数字设备"项目的研发工作。 <br />32.  四川移动通信有限责任公司数据心业务软件研发中心 <br /> 四川移动通信有限责任公司数据心业务软件研发中心于6月16日落户成都高新区。四川移动通信有限公司是世界500强企业中国移动通信集团的全资子公司，是四川省内最具竞争力的通信运营企业，在通信设备制造、新技术研发、网络运营等领域有较强的影响力和号召力。 <br />33.  金山数字娱乐科技有限公司 (成都)<br />金山数字娱乐科技有限公司成都分公司于4月25日落户高新区，致力于数字娱乐软件的研发。金山进入成都高新区打算在几年内成为成都规模最大的本地软件企业之一，并使成都金山研发产品成为国内国际上的知名品牌。金山CEO雷军表示，"京珠两地研发人才奇缺，竞争激烈，而且各种成本居高不下，成都是金山今后发展新研发基地首选。" 
<div class="Pbb659">字串5</div><br />34.  中兴通讯（成都）研发中心 <br /> 中兴通讯股份有限公司是中国最大的通信设备制造业上市公司，是我国通信基础设施建设的主要设备供应商之一。中兴通讯股份有限公司在成都高新区南部园区设立了研发中心，占地面积33350平方米，建筑面积40000平方米，总投资2亿元，从业人员约2500人。 <br />35. 华为（成都）研究所 <br /> 深圳华为技术有限公司是中国电子行业知名企业，连续4年位居"中国软件产业最大规模前100家企业"榜首。华为（成都）研究所位于成都高新区南部园区，建筑面积5000平方米，从业人员约200人，主要从事光网络的技术开发。 <br />36. 科胜讯公司成都研发中心 <br /> 科胜讯（Conexant）公司是世界排名第十的IC设计公司，是宽带通讯、企业网络和数字化家庭等应用半导体解决方案全球领导厂商。科胜讯在全世界共有60个办事机构，该公司拟在成都高新区投资200万美元建设IC设计中心。<br />详情：</font>
						<a href="http://www.chinaeda.com/">
								<font color="#002c99" size="4">www.chinaeda.com</font>
						</a>
						<br />
				</p>
				<p class="Pbb659">ARM开发论坛</p>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-19 13:02 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/19/50400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何学习嵌入式系统（基于ARM平台）</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50399.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 19 Oct 2008 05:01:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50399.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50399.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50399.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50399.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50399.html</trackback:ping><description><![CDATA[
		<h1>如何学习嵌入式系统（基于ARM平台）</h1>
		<div id="entrymeta">发表时间:2008-09-17 08:47:55 来源: 责任编辑:阿壬 阅读数:
<script language="javascript" src="/plus/count.php?view=yes&amp;aid=3882&amp;mid=0"></script>
 712</div>
		<div class="clear">
		</div>
		<div id="entrybody">
				<div id="entryadbox">
				</div>
				<style><![CDATA[.Vte239 { display:none; } ]]&gt;</style>
				<p>
						<font size="4">                                         <br />来源：中嵌学院<br />前言<br />   网上看到众多网友都问了关于嵌入式系统方面的很多问题，很多都可在这里找到答案，希望我的这篇文章能给他们以启发。也请大家不要轻易转载。</font>
				</p>
				<p class="Vte239">字串4</p>
				<p>
				</p>
				<p>
						<font size="4">一、嵌入式系统的概念<br />   <br />    着重理解“嵌入”的概念 </font>
						<font color="#ffffff">http://www.armforum.cn</font>
				</p>
				<p>
						<font size="4">    主要从三个方面上来理解。<br />    1、从硬件上，将基于CPU的处围器件，整合到CPU芯片内部，比如早期基于X86体系结构下的计算机，CPU只是有运算器和累加器的功能，一切芯片要造外部桥路来扩展实现，象串口之类的都是靠外部的16C550/2的串口控制器芯片实现，而目前的这种串口控制器芯片早已集成到CPU内部，还有PC机有显卡，而多数嵌入式处理器都带有LCD控制器，但其种意义上就相当于显卡。比较高端的ARM类Intel Xscale架构下的IXP网络处理器CPU内部集成PCI控制器（可配成支持4个PCI从设备或配成自身为CPI从设备）；还集成3个NPE网络处理器引擎，其中两个对应于两个MAC地址，可用于网关交换用，而另外一个NPE网络处理器引擎支持DSL，只要外面再加个PHY芯片即可以实现DSL上网功能。IXP系列最高主频可以达到1.8G，支持2G内存，1G×10或10G×1的以太网口或Febre channel的光通道。IXP系列应该是目标基于ARM体系统结构下由intel进行整合后成Xscale内核的最高的处理器了。<br />    2、从软件上前，就是在定制操作系统内核里将应用一并选入，编译后将内核下载到ROM中。而在定制操作系统内核时所选择的应用程序组件就是完成了软件的“嵌入”，比如WinCE在内核定制时，会有相应选择，其中就是wordpad,PDF,MediaPlay等等选择，如果我们选择了，在CE启动后，就可以在界面中找到这些东西，如果是以前PC上将的windows操作系统，多半的东西都需要我们得新再装。 
<p class="Vte239">ARM</p><br />    3、把软件内核或应用文件系统等东西烧到嵌入式系统硬件平台中的ROM中就实现了一个真正的“嵌入”。</font>
				</p>
				<div class="Vte239">字串8</div>
				<p>
				</p>
				<p>
						<font size="4">    以上的定义是我在6、7年前给嵌入式系统下自话侧重于理解型的定义，书上的定义也有很多，但在这个领域范围内，谁都不敢说自己的定义是十分确切的，包括那些专家学者们，历为毕竟嵌入式系统是计算机范畴下的一门综合性学科</font>
				</p>
				<div class="Vte239">M开发论坛</div>
				<p>
				</p>
				<p>
						<br />
						<font size="4">二、嵌入式系统的分层与专业的分类。<br />   <br />    嵌入式系统分为４层，硬件层、驱动层、操作系统层和应用层。 </font>
				</p>
				<div class="Vte239">字串5</div>
				<p>
				</p>
				<p>
						<font size="4">　　1、硬件层，是整个嵌入式系统的根本，如果现在单片机及接口这块很熟悉，并且能用C和汇编语言来编程的话，从嵌入式系统的硬件层走起来相对容易，硬件层也是驱动层的基础，一个优秀的驱动工程师是要能够看懂硬件的电路图和自行完成CPLD的逻辑设计的，同时还要对操作系统内核及其调度性相当的熟悉的。但硬件平台是基础，增值还要靠软件。<br />    硬件层比较适合于，电子、通信、自动化、机电一体、信息工程类专业的人来搞，需要掌握的专业基础知识有，单片机原理及接口技术、微机原理及接口技术、C语言。<br />    2、驱动层，这部分比较难，驱动工程师不仅要能看懂电路图还要能对操作系统内核十分的精通，以便其所写的驱动程序在系统调用时，不会独占操作系统时间片，而导至其它任务不能动行，不懂操作系统内核架构和实时调度性，没有良好的驱动编写风格，按大多数书上所说添加的驱动的方式，很多人都能做到，但可能连个初级的驱动工程师的水平都达不到，这样所写的驱动在应用调用时就如同windows下我们打开一个程序运行后，再打开一个程序时，要不就是中断以前的程序，要不就是等上一会才能运行后来打开的程序。想做个好的驱动人员没有三、四年功底，操作系统内核不研究上几编，不是太容易成功的，但其工资在嵌入式系统四层中可是最高的。 <font color="#ffffff">字串5</font><br />    驱动层比较适合于电子、通信、自动化、机电一体、信息工程类专业尤其是计算机偏体系结构类专业的人来搞，除硬件层所具备的基础学科外，还要对数据结构与算法、操作系统原理、编译原理都要十分精通了解。</font>
				</p>
				<p class="Vte239">字串5</p>
				<p>
				</p>
				<p>
						<font size="4">   3、操作系统层，对于操作系统层目前可能只能说是简单的移植，而很少有人来自已写操作系统，或者写出缺胳膊少腿的操作系统来，这部分工作大都由驱动工程师来完成。操作系统是负责系统任务的调试、磁盘和文件的管理，而嵌入式系统的实时性十分重要。据说，XP操作系统是微软投入300人用两年时间才搞定的，总时工时是600人年，中科院软件所自己的女娲Hopen操作系统估计也得花遇几百人年才能搞定。因此这部分工作相对来讲没有太大意义。</font>
						<span class="Vte239">http://www.armforum.cn</span>
				</p>
				<p>
						<font size="4">   4、应用层，相对来讲较为容易的，如果会在windows下如何进行编程接口函数调用，到操作系统下只是编译和开发环境有相应的变化而已。如果涉及Jave方面的编程也是如此的。嵌入式系统中涉及算法的由专业算法的人来处理的，不必归结到嵌入式系统范畴内。但如果涉及嵌入式系统下面嵌入式数据库、基于嵌入式系统的网络编程和基于某此应用层面的协议应用开发（比如基于SIP、H.323、Astrisk）方面又较为复杂，并且有难度了。<br />三、目标与定位。<br />    先有目标，再去定位。 <br />    学ARM，从硬件上讲，一方面就是学习接口电路设计，另一方面就是学习汇编和C语言的板级编程。如果从软件上讲，就是要学习基于ARM处理器的操作系统层面的驱动、移植了。这些对于初学都来说必须明确,要么从硬件着手开始学，要么从操作系统的熟悉到应用开始学，但不管学什么，只要不是纯的操作系统级以上基于API的应用层的编程，硬件的寄存器类的东西还是要能看懂的，基于板级的汇编和C编程还是要会的。因此针对于嵌入式系统的硬件层和驱动程的人，ARM的接口电路设计、ARM的C语言和汇编语言编程及调试开发环境还是需要掌握的。<br />    因此对于初学者必然要把握住方向，自己的目标是什么，自己要在那一层面上走。然后再着手学习较好，与ARM相关的嵌入式系统的较为实际的两个层面硬件层和驱动层，不管学好了那一层都会很有前途的。 <font color="#ffffff">字串4</font><br />    如果想从嵌入式系统的应用层面的走的话，可能与ARM及其它体系相去较远，要着重研究基嵌入式操作系统的环境应用与相应开发工具链，比如WinCe操作系统下的EVC应用开发（与windows下的VC相类似），如果想再有突破就往某些音视频类的协议上靠，比如VOIP领域的基于SIP或H.323协议的应用层开发，或是基于嵌入式网络数据库的开发等等。</font>
				</p>
				<div class="Vte239">字串4</div>
				<p>
				</p>
				<p>
						<font size="4">    对于初学者来讲，要量力而行，不要认为驱动层工资高就把它当成方向了，要结合自身特点，嵌入式系统四个层面上那个层面上来讲都是有高人存在，当然高人也对应的高工资，我是做硬件层的，以前每月工资中个人所得税要被扣上近3千大元，当然我一方面充当工程师的角色，一方面充当主管及人物的角色，两个职位我一个人干，但上班时间就那些。硬件这方面上可能与我PK的人很少了，才让我拿到那么多的工资。   <br />四、开发系统选择。<br />    很多ARM初学者都希望有一套自己能用的系统，但他们住住会产生一种错误认识就是认为处理器版本越高、性能越高越好，就象很多人认为ARM9与ARM7好，我想对于初学者在此方面以此入门还应该理智，开发系统的选择最终要看自己往嵌入式系统的那个方向上走，是做驱动开发还是应用，还是做嵌入式系统硬件层设计与板级测试。如果想从操作系统层面或应用层面上走，不管是驱动还是应用，那当然处理器性能越高越好了，但这个东西自学，有十分大的困难，不是几个月或半年或是一年二年能搞定的事。<br />  　在某种意义上请，ARM7与9的差别就是在某些功能指令集上丰富了些，主频提高一些而已，就比如286和386。对于用户来讲可能觉查不到什么，只能是感觉速度有些快而已。 <span class="Vte239">ARM</span><br />　　ARM7比较适合于那些想从硬件层面上走的人，因为ARM7系列处理器内部带MMU的很少，而且比较好控制，就比如S3C44B0来讲，可以很容易将Cache关了，而且内部接口寄存器很容易看明白，各种接口对于用硬件程序控制或AXD单步命令行指令都可以控制起来，基于51单片机的思想很容易能把他搞懂，就当成个32位的单片机，从而消除很多51工程师想转为嵌入式系统硬件ARM开发工程师的困惑，从而不会被业界某此不是真正懂嵌入式烂公司带到操作系统层面上去，让他们望而失畏，让业界更加缺少这方面的人才。<br />    而嵌入式系统不管硬件设计还是软件驱动方面都是十分注重接口这部分的，选择平台还要考察一个处理器的外部资源，你接触外部资源越多，越熟悉他们那你以后就业成功的机率就越高，这就是招聘时所说的有无“相关技能”，因为一个人不可能在短短几年内把所有的处理器都接触一遍，而招聘单位所用的处理器就可能是我们完全没有见过的，就拿台湾数十家小公司（市价几千万）的公司生产的ARM类处理器，也很好用，但这些东西通用性太差，用这些处理器的公司就只能招有相关工作经验的人了，那什么是相关工作经验，在硬件上讲的是外围接口设计，在软件上讲是操作系统方面相关接口驱动及应用开发经验。我从业近十年，2000年ARM出现，我一天始做ARM7,然后直接跑到了Xscale（这个板本在ARM10-11之间），一做就是五年，招人面试都不下数百人，在这些方面还是深有体会的。　　 
<div class="Vte239">http://www.armforum.cn</div><br />    我个人认为三星的S3C44b0对初学者来说比较合适，为什么这么说哪？因为接口资源比较丰富，技术成熟，资料较多，应该十分适合于初学者，有问题可能很容易找人帮且解决，因为大多数人都很熟悉，就如同51类的单片机，有N多位专家级的人物可以给你帮忙，相关问题得以很快解答，所然业界认为这款ARM都做用得烂了，但对于初学者来，就却是件好事。<br />    因此开发系统的选择，要看自己的未来从来目标方向、要看开发板接口资源、还要看业界的通用性。<br />五、如何看待培训。<br />    首先说说我自己，我目前从业近十年，与国内嵌入式系统行业共同起步，一直站在嵌入式系统行业前沿，设计过多款高端嵌入式系统平台产品并为众多公司提供过解决方案，离职前为从事VOIP的美资公司设计IP-PBX，历任项目经理、项目主管、技术总监、部门经理，积累众多人脉，并集多年经验所得，考虑到学生就业与公司招人的不相匹配，公司想招人招不到，而学生和刚毕业的工程师想找份工作也不太容易，于此力创知天行科技有限公司，开展嵌入式系统教育培训。<br />    因一线的科研人员和一线的教师不相接触，导至国内嵌入式人才缺乏，国外高校的技术超前于业界公司，而国内情况是业界公司方面的嵌入式系统技术要远远领先于高校。为架构业界与高校沟通的桥梁，把先进技能带给高校学子，为学生在就业竞争中打造一张王牌，并为业界工程师快速提升实现自我创造机遇，我就这样辞去了外企年薪20多万的职位，做嵌入式系统方面的培训了。 <span class="Vte239">字串8</span><br />    对于培训来讲，是花钱来买时间，很多工程师都喜欢自己学，认为培训不值，这也是有可能的，纯为赚钱的培训当然不会太有价值，但对于实力型的培训他们可能就亏大了，有这样一笔帐不知他们算过没有，如果一个一周的培训，能带给他们自学两年后才能掌握的知识，在培训完后他们用三个月到半年时间消化培训内容，这样他会省约至少一年半的时间来学其它的或重新站在另一个高度上工作，那么他将最迟一年后会拿到他两年后水平所对应的工资，就是在工资与水平对应的关系上比同批人缩短一年，每月按最少1千计，再减去培训费用至少多1.0万，同时也省了一年时间，不管是休闲也好，再继续提高也好，总之是跑到了队伍的前面了。<br />    另一层面上讲，对于新人的培训相当于他们为自己提前买了份失业保险，有师傅会带领他们入道，我今年暑假时班里最年轻的一个学生是大二的，今年才上大三，这学期才刚学单片机，但现在ARM方面的编程工作已经搞得有声有色了，再过一年多毕业，他还会失业吗？<br />    再者通过培训，你可以知道很多业界不为常人所知的事，同时也为自己找了个师傅，就比如说，两个工程师分别用S3C2410和PXA255来做手持设备，同样两人都工作四年，再出去找工作，两人工资可能最多可相差一倍，为什么？这就是业界不为常人所知的规则，2410属于民品，被业界用烂了，做产品时成本特敏感，当然也对人才成本敏感了，PXA255是intel的东西，一个255 CPU能买三个2410，一直被业界定义为贵族产品，用的公司都是大公司或为军方服务的公司，不会在乎成本，只要把东西做好，一切都好说，但这方面做的人也少啊，因为开发系统贵啊。 <font color="#ffffff">字串8</font><br />    对于说为自已找了个好师傅，我想是这样的，因为同级工程师间存在着某此潜在的竞争关系，有很多人不愿意把自己知道的东西教给别人，这意味着他将要失业，就是所说的教会徒弟，饿死师傅，但对于我们这些人就不存在这样的关系了，我是在嵌入式系统平台设计上走到了一定程序，目前在国内这块的技术上已经是自己很难再突破自己，因此很多东西我对大家都是OPEN的，就比如说下面那部分关于接口设计中所提到的时序接口东西，我要是不讲，却使是高级硬件工程师我想也几乎只有10%的人能知道吧。<br />    六、成为高级嵌入式系统硬件工程师要具备的技能。<br />       首先我声明，我是基于嵌入式系统平台级设计的，硬件这个方向我相对来讲比较有发言权，如果是其它方面所要具备的基本技能还要和我们培训中心其它专业级讲师沟通，或去网站看看</font>
						<a href="http://www.zt-training.com/">
								<font size="4">www.zt-training.com</font>
						</a>
						<font size="4">。他们的方面上我只能说是知道些，但不是太多，初级的问题也可以问我。<br />    对于硬件来讲有几个方向，就单纯信号来分为数字和模拟，模拟比较难搞，一般需要很长的经验积累，单单一个阻值或容值的精度不够就可能使信号偏差很大。因此年轻人搞的较少，随着技术的发展，出现了模拟电路数字化，比如手机的Modem射频模块，都采用成熟的套片，而当年国际上只有两家公司有此技术，自我感觉模拟功能不太强的人，不太适合搞这个，如果真能搞定到手机的射频模块，只要达到一般程度可能月薪都在15K以上。 <font color="#ffffff">字串4</font><br />    另一类就是数字部分了，在大方向上又可分为51/ARM的单片机类，DSP类，FPGA类，国内FPGA的工程师大多是在IC设计公司从事IP核的前端验证，这部分不搞到门级，前途不太明朗，即使做个IC前端验证工程师，也要搞上几年才能胜任。DSP硬件接口比较定型，如果不向驱动或是算法上靠拢，前途也不会太大。而ARM单片机类的内容就较多，业界产品占用量大，应用人群广，因此就业空间极大，而硬件设计最体现水平和水准的就是接口设计这块，这是各个高级硬件工程师相互PK，判定水平高低的依据。而接口设计这块最关键的是看时序，而不是简单的连接，比如PXA255处理器I2C要求速度在100Kbps，如果把一个I2C外围器件，最高还达不到100kbps的与它相接，必然要导致设计的失败。这样的情况有很多，比如51单片机可以在总线接LCD，但为什么这种LCD就不能挂在ARM的总线上，还有ARM7总线上可以外接个Winband的SD卡控制器，但为什么这种控制器接不到ARM9或是Xscale处理器上，这些都是问题。因此接口并不是一种简单的连接，要看时序，要看参数。 一个优秀的硬件工程师应该能够在没有参考方案的前提下设计出一个在成本和性能上更加优秀的产品，靠现有的方案，也要进行适当的可行性裁剪，但不是胡乱的来，我遇到一个工程师把方案中的5V变1.8V的DC芯片，直接更换成LDO，有时就会把CPU烧上几个。前几天还有人希望我帮忙把他们以前基于PXA255平台的手持GPS设备做下程序优化，我问了一下情况，地图是存在SD卡中的，而SD卡与PXA255的MMC控制器间采用的SPI接口，因此导致地图读取速度十分的慢，这种情况是设计中严重的缺陷，而不是程序的问题，因此我提了几条建议，让他们更新试下再说。因此想成为一个优秀的工程师，需要对系统整体性的把握和对已有电路的理解，换句话说，给你一套电路图你终究能看明白多少，看不明白80%以上的话，说明你离优秀的工程师还差得远哪。其次是电路的调试能力和审图能力，但最最基本的能力还是原理图设计PCB绘制，逻辑设计这块。这是指的硬件设计工程师，从上面的硬件设计工程师中还可以分出ECAD工程师，就是专业的画PCB板的工程师，和EMC设计工程师，帮人家解决EMC的问题。硬件工程师再往上就是板级测试工程师，就是C语功底很好的硬件工程师，在电路板调试过程中能通过自已编写的测试程序对硬件功能进行验证。然后再交给基于操作系统级的驱动开发人员。 
<p class="Vte239">ARM</p><br />    总之，硬件的内容很多很杂，硬件那方面练成了都会成为一个高手，我时常会给人家做下方案评估，很多高级硬件工程师设计的东西，经常被我一句话否定，因此工程师做到我这种地步，也会得罪些人，但硬件的确会有很多不为人知的东西，让很多高级硬件工程师也摸不到头脑。 <br />    那么高级硬件件工程师技术技能都要具备那些东西哪，首先要掌握EDA设计的辅助工具类如Protel\ORCAD\PowperPCB\Maplux2\ISE、VDHL语言，要能用到这些工具画图画板做逻辑设计，再有就是接口设计审图能力，再者就是调试能力，如果能走到总体方案设计这块，那就基本上快成为资深工程师了。<br />    硬件是要靠经验，也要靠积累的，十年磨一剑，百年磨一针。<br />    把一个月前想写的东西，今天终于用一上午的进间整理完了，希望对喜爱嵌入式系统开发的工程师和学生们有所帮助。</font>
				</p>
				<div class="Vte239">字串8</div>
				<p>
				</p>
				<p>
						<font size="4">详情况：</font>
						<a href="http://www.chinaeda.com/">
								<font size="4">www</font>
						</a>
				</p>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50399.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-19 13:01 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/19/50399.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ubuntu是什么？</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50398.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 19 Oct 2008 04:49:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50398.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50398.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50398.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50398.html</trackback:ping><description><![CDATA[ubuntu是什么？是一款Linux，他又不仅仅是一款Linux，他已经超越了Linux，更是代表着Linux的自由精神与Ubuntu 精神（人道待人）的结合。<br /><br />而作为现在网络上最流行的Linux发行版本，他拥有着上手容易的优点，一改人们对Linux入门难的偏见，而且拥有非常炫的3D桌面（注：这并不是ubuntu特有的，Linux发行版本都有）等等吸引眼球的事物，对于开发者，也有为数众多的开发软件供其选择，最后ubuntu还承诺永远免费，你在使用过程中无需为其花费一分钱，这就是自由软件的优点，请注意free software中的free是代表着自由而不是免费的意思，如果翻译成免费的话，那么这个定义就太狭隘了。<br /><br /><img src ="http://www.cnitblog.com/guopingleee/aggbug/50398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-19 12:49 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/19/50398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>怎样才能学好linux？</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50397.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 19 Oct 2008 03:02:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50397.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50397.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50397.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50397.html</trackback:ping><description><![CDATA[
		<div style="LINE-HEIGHT: 22px; HEIGHT: 22px">
				<div style="FLOAT: left">
						<img alt="发贴心情" src="http://www.farsight.com.cn/FarsightBBS/skins/Default/topicface/face1.gif" />
				</div>
				<b>怎样才能学好linux？</b>
		</div>
		<div style="PADDING-RIGHT: 0px; MARGIN-TOP: 10px; FONT-SIZE: 9pt; OVERFLOW-X: hidden; WIDTH: 97%; WORD-BREAK: break-all; TEXT-INDENT: 24px; LINE-HEIGHT: normal; HEIGHT: 200px; WORD-WRAP: break-word" onload="this.style.overflowX='auto';">
				<p>
						<font color="#3300ff">学习嵌入式linux，首先要了解通用的linux操作系统，下面转载网上一篇介绍如何学习linux的笔记，感觉写得不错，思路比较清晰，希望对大家的学习有所帮助～～</font>
				</p>
				<p>
				</p>随着Linux应用的扩展许多朋友开始接触Linux，根据学习Windwos的经验往往有一些茫然的感觉：不知从何处开始学起。这里介绍学习Linux的一些建议。 
<p></p>一、从基础开始： 常常有些朋友在Linux论坛问一些问题，不过，其中大多数的问题都是很基础的。例如：为什么我使用一个命令的时候，系统告诉我找不到该目录，我要如何限制使用者的权限等问题，这些问题其实都不是很难的，只要了解了 Linux 的基础之后，应该就可以很轻易的解决掉这方面的问题。而有些朋友们常常一接触Linux 就是希望构架网站，根本没有想到要先了解一下Linux 的基础。这是相当困难的。 
<p></p>二、Linux命令是必须学习 虽然Linux桌面应用发展很快，但是命令在Linux中依然有很强的生命力。Linux是一个命令行组成的操作系统,精髓在命令行，无论图形界面发展到什么水平这个原理是不会变的，Linux命令有许多强大的功能：从简单的磁盘操作、文件存取、到进行复杂的多媒体图象和流媒体文件的制作。举一个例子:Linux的常用命令find,察看man文档,初学者一定会觉得太复杂而不原意用,但是你一旦学会就爱不释手.它的功能实在太强了,在配合exec参数或者通过管道重定向到xargs命令和grep命令,可以完成非常复杂的操作,如果同样的操作用图形界面的工具来完成,恐怕要多花十几陪的时间. 不同版本的Linux命令数量不一样，这里笔者把它们中比较重要的和使用频率最多的命令，按照它们在系统中的作用分成几个部分介绍给大家，通过这些基础命令的学习我们可以进一步理解Linux系统： 安装和登录命令：login、 shutdown、 halt、 reboot 、mount、umount 、chsh 文件处理命令：file、 mkdir、 grep、dd、 find、 mv 、ls 、diff、 cat、 ln 系统管理相关命令： df、 top、 free、 quota 、at、 lp、 adduser、 groupadd kill、 crontab、 tar、 unzip、 gunzip 、last 网络操作命令：ifconfig、 ip 、ping 、 netstat 、telnet、 ftp、 route、 rlogin rcp 、finger 、mail 、nslookup 系统安全相关命令： passwd 、su、 umask 、chgrp、 chmod、chown、chattr、sudo、 pswho 
<p></p>三、选择一本好的工具书 工具书对于学习者而言是相当重要的。一本错误观念的工具书却会让新手整个误入歧途。目前国内关于Linux的书籍有很多不过精品的不多，笔者强烈建议阅读影印本的“O'Reilly原版Linux图书<a href="http://www.oreilly.com.cn/" target="_blank"><a href="http://www.oreilly.com.cn/" target="_blank"><font color="#002c99">http://www.oreilly.com.cn/</font></a></a> ”，而且出版社还提供了一个非常好的路线图：<a href="http://www.oreilly.com.cn/guide/guide_linux.php" target="_blank"><a href="http://www.oreilly.com.cn/guide/guide_linux.php" target="_blank"><font color="#002c99">http://www.oreilly.com.cn/guide/guide_linux.php</font></a></a>。 
<p></p>四、选择一个适合你的Linux发行版本 目前全球有超过1百多个Linux发行版本，在国内也能找到十几个常见版本。如何选择请根据你的需求和能力，Redhat Linux 和Debian Linux是网络管理员的理想选择。对于英语不是很好的读者红旗Linux、中标Linux这些中文版本比较适合。现在一些Linux网站有一些Linux版本的免费下载，这里要说的是并不适合Linux初学者。 
<p></p>五、 养成在命令行下工作： 一定要养成在命令行下工作的习惯，要知道X－window只是运行在命令行模式下的一个应用程序。在命令行下学习虽然一开始进度较慢，但是熟悉后，您未来的学习之路将是以指数增加的方式增长的。从网管员来说，命令行实际上就是规则，它总是有效的，同时也是灵活的。即使是通过一条缓慢的调制解调器线路，它也能操纵几千公里以外地远程系统。 
<p></p>六、 选择一个适合你的Linux社区； 随着Linux应用的扩展，出现了不少Linux社区。其中有一些非常优秀的社区：<a href="http://www.linuxforum.net/" target="_blank"><a href="http://www.linuxforum.net/" target="_blank"><font color="#002c99">www.linuxforum.net</font></a></a>（国内最高水平GNU站点）、<a href="http://www.chinaunix.net/" target="_blank"><a href="http://www.chinaunix.net/" target="_blank"><font color="#002c99">http://www.chinaunix.net/</font></a></a> （中国最大的Unix技术社区），但是这几个论坛往往是Linux高手的舞台，如果在探讨高级技巧的论坛张贴非常初级的问题经常会没有结果。 
<p></p>七、勤于实践： 要增加自己Linux 的技能，只有通过实践来实现了。所以，赶快找一部计算机，赶快安装一个 Linux 发行版本，然后进入精彩的Linux世界。相信对于你自己的 Linux 能力必然大有斩获。此外，人脑不像计算机的硬盘一样，除非硬盘坏掉了或者是资料被你抹掉了，否则储存的资料将永远而且立刻的记忆在硬盘中。在人类记忆的曲线中，你必须要不断的重复练习才会将一件事情记得比较熟。同样的，学习 Linux 也一样，如果你无法经常学习的话，学了后面的，前面的忘了。你对Linux命令熟悉后你可以开始搭建一个小的Linux网络，这是最好的实践方法。Linux是网络的代名词，Linux网络服务功能非常强大，不论是邮件服务器、Web服务器、DNS服务器等都非常完善。当然你不需搭建所有服务，可以慢慢来。需要说明的是这个Linux网络对于初学者有两三台计算机即可，其中一台计算机最好安装Windows系统。自己多动手，不要非要等着别人帮你解决问题。 
<p></p>八、 如何得到联机帮助 和私有操作系统不同，各个Linux的发行版本的技术支持时间都较短，这对于Linux初学者是往往不够的。其实当你安装了一个完整的Linux系统后其中已经包含了一个强大的帮助，只是可能你还没有发现和使用它们的技巧。 
<p></p>1. 主流Linux发行版都自带非常详细的文档（包括手册页和FAQ），从系统安装到系统安全,针对不同层次的人的详尽文档，仔细阅读文档后40%问题都可在此解决。 
<p></p>2. 查阅经典工具书和Howto，特别是Howto是全球数以万计的Linux、Unix的经验总结非常有参考价值通常40％的问题同样可以解决。 
<p></p>九、在Linux论坛获取帮助 如果上面的措施没有解决问题，此时你就需要Linux社区的帮助了。Linux的使用者一般都是专业人士，他们有着很好的电脑背景且愿意协助他人，Linux高手更具有鼓励新手的文化精神。如何在Linux社区获得帮助，需要说明的是你要有周全的思考，准备好你的问题，不要草率的发问，否则只会得到到草率的回答或者根本得 不到任何答案。越表现出在寻求帮助前为解决问题付出的努力，你越能得到实质性的帮助。最好先搜寻一下论坛是否有您需要的文章。这样可以获得事半功倍的效果。 下面笔者在论坛看到的一个好问题：“安装红旗4.0 后，系统紫光输入法自带的双拼方案和我的习惯不一样，如何自定义双拼方案解决?谢谢？”这个问题很简练，笔者五分钟后就给出了解决方法：“首先备份原文件到其他目录，然后删掉/usr/local/unispim/unispimsp.ksc，编辑/usr/local/unispim/unispimsp.ini ，最后重启动计算机，生成新的unispimsp.ksc”另外得到回复后如果问题解决，向帮助过你的人发个说明，让他们知道问题是怎样解决的，这种补充有助于他人在邮件列表/新闻组/论坛中搜索对你有过帮助的完整解决方案，这可能对他们也很有用。 下面看看一个让人无法回答的问题：“救命各位高手，向你们请教一些问题：如何在Linux下配制HTTP、FTP、Samba、DNS、DHCP、Sendmail服务器，谢谢” 这样的问题我想即使Linux高手也很难快速准确精练的回答你。 你需要提供精确有效的信息。这并不是要求你简单的把成吨的出错代码或者数据完全转储摘录到你的提问中。如果你有庞大而复杂的测试条件，尽量把它剪裁得越小越好。可能你会遇到这种情况，对于一个问题会出现不同内容回答，这时你需要通过实践来验证。另外把这个问题放在其他Linux社区请求帮助也是一种选择。如果得不到答案，请不要以为我们觉得无法帮助你。有时只是看到你问题的人不知道答案罢了。这时换一个社区是不错的选择。 另外发问的时候一定要注意到某些礼节。因为Linux社区是一个松散的组织、也不承担回复每个帖子的义务。它不是技术支持。 
<p></p>十．用Unix思维学习Linux Linux是参照Unix思想设计的，理解掌握Linux必须按照Unix思维来进行。思想性的转变比暂时性的技术提高更有用,因为他能帮助你加快学习速度。 
<p></p>十一．学习专业英文 如果你想深入学习Linux,看不懂因为文档实在是太难了。写的最好的,最全面的文档都是英语写的,最先发布的技术信息也都是用英语写的。即便是非英语国家的人发布技术文档,也都首先翻译成英语在国际学术杂志和网络上发表。安装一个新的软件时先看README,再看INSTALL然后看FAQ,最后才动手安装,这样遇到问题就知道为什么。如果说明文档不看,结果出了问题再去论坛来找答案反而浪费时间。 
<p></p>十二.最后是Linux学习的路线图： 
<p></p>1． 掌握至少50个以上的常用命令。 
<p></p>2． 熟悉Gnome/KDE等X-windows桌面环境操作 。 
<p></p>3． 掌握.tgz、.rpm等软件包的常用安装方法 
<p></p>4． 学习添加外设，安装设备驱动程序（比如网卡） 
<p></p>5． 熟悉Grub/Lilo引导器及简单的修复操作 。 
<p></p>6． 熟悉Linux文件系统和目录结构。 
<p></p>7． 掌握vi,gcc,gdb等常用编辑器，编译器，调试器。Linux下编程，主要是选用一个文本编辑工具（如vi eclipse nano gedit等)编写，再用GCC编译链接，最后用gdb调试。 
<p></p>8． 理解shell别名、管道、I/O重定向、输入和输出以及shell脚本编程。 
<p></p>9． 学习Linux环境下的组网。 <br /><p></p><p><strong>学习嵌入式linux，也有三个方向：</strong></p><p></p>1、嵌入式linux应用软件开发 
<p></p>2、linux内核的剪裁和移植 
<p></p>3、嵌入式linux底层驱动的开发 
<p></p>无论选择哪一方向，基本的linux的知识是需要具备的，其他还需要掌握的知识有ARM（最常用的一款嵌入式处理器）和C语言编程，每一方面知识的掌握熟练程度都最终决定了个人进行嵌入式linux开发的综合能力。<br /><br /><br /><br /><div align="right"><font color="#000066">[此贴子已经被作者于2007-4-3 21:38:02编辑过]</font></div></div>
		<div style="OVERFLOW-X: hidden; WIDTH: 85%">
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-19 11:02 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/19/50397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>嵌入式编程思想——集网上精华于一体（强烈推荐给大家）</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50396.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 19 Oct 2008 02:51:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50396.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50396.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/19/50396.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50396.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50396.html</trackback:ping><description><![CDATA[
		<strong>嵌入式编程思想——集网上精华于一体（强烈推荐给大家）</strong>
		<div style="PADDING-RIGHT: 0px; MARGIN-TOP: 10px; FONT-SIZE: 9pt; OVERFLOW-X: hidden; WIDTH: 97%; WORD-BREAK: break-all; TEXT-INDENT: 24px; LINE-HEIGHT: normal; HEIGHT: 200px; WORD-WRAP: break-word" onload="this.style.overflowX='auto';">
				<p>
						<font color="#ff0033">
								<strong>admin注：有网友说无法下载，所以偶重新帮LZ传了一下！</strong>
						</font>
				</p>
				<p>
				</p>
				<strong>
						<font color="#0033ff">
								<a href="http://www.farsight.com.cn/download/ebook.rar" target="_blank">单击此处下载</a>
						</font>
				</strong>
				<p>
				</p>本书为目前互联网上分类最清晰，讲解最精彩的一本书，而且完全免费向大家提供，希望给大家一个很好的交流学习氛围，作者给书起名为：嵌入式编程思想，可见其用心精良。 
<p></p><br /><div><br /><p><b>致谢： </b></p><p></p>谨以此书献给我的女友：<i>Tangxuan</i>，是她给予我莫大的激情和动力来完成本书，如果没有她默默的关心和支持，或许这本书至今仍只是一个构想，是她使我能梦想成真把这本书贡献给大家。<font face="Verdana"></font><p></p>感谢我的母亲，正至母亲节，虽然现在我不能在她身边陪她，但是她谆谆教诲一直影响着我的一生，感谢我的父亲，是他教会了我做人的道理。 
<p></p>感谢<a href="http://www.wsnforum.org/" target="_blank"><font color="#000000">嵌入式技术网</font></a>，本书大部分资料来源于此，感谢<a href="http://www.wsnforum.org/" target="_blank"><font color="#000000">嵌入式技术网</font></a>的管理员、版主和会员，他们的热情为本书提供了创作的源泉。 
<p></p>感谢所有关心我的人，是他们使我有了一个良好的学习、生活、交流的氛围。 
<p></p>Dedication 
<p></p><i>To My girlfriend Tangxuan, whose courage and determination are an everyday guiding light,I love her for ever, and to My mother and Dad, whose foresight and education are an everlasting source of inspiration,and to everyone who take care of me,thanks.</i><p></p>—<a href="mailto:aqbhc@163.com" target="_blank"><font color="#000000">Zhengyu</font></a><p></p>2006-5-13 
<p></p><strong><font color="#0000ff">本书结构如下：</font></strong><p></p><strong>二、嵌入式基础－嵌入式开发环境构建</strong><p></p>1、软硬件环境构建－构建宿主机和目标机软硬件环境，构建交*编译、连接、调试环境，集成开发环境等,  安装开发工具和文件、 配置超级终端/minicom、配置TFTP网络服务、 配置NFS网络服务、引导目标板启动Linux内核、交*编译应用程序、交*调试应用程序，嵌入式Linux开发环境构建。 
<p></p>      1.1 交*开发环境介绍 
<p></p>      1.2 编译交*开发工具链 
<p></p>      1.3 配置主机开发环境 
<p></p>      1.4 建立交*开发环境 
<p></p>      1.5 交*调试应用程序 
<p></p>2、启动引导技术－Bootloader技术分析与移植，U－BOOT分析与移植、开发系统引导程序、 Bootloader介绍、u-boot工程介绍、 u-boot的编译使用、u-boot源码分析、u-boot移植过程。 
<p></p>3、内核移植技术－配置编译Linux内核、嵌入式linux内核移植，ARM-Linux内核移植，uClinux内核移植等。 
<p></p>4、文件系统构建－构建嵌入式文件系统，JFFS,YAFFS，NFS文件系统构建，部署Ramdisk文件系统的过程，部署JFFS2文件系统的过程。 
<p></p><strong>三、嵌入式编程技术</strong><p></p>1、汇编语言－ARM指令与汇编语言。 
<p></p>2、C/C++/Java－深入C/C++/Java编程语言，掌握在嵌入式下面的使用方法，GCC工具链进行远程交*编译、连接、调试，J2ME移动编程技术。 
<p></p>3、通信编程技术－涉及socket、BSD套接字通信编程，设备之间进行通信，基于嵌入式Linux的TCP/IP网络结构， 基于嵌入式Linux的socket编程。 
<p></p>4、嵌入式数据库编程－MYSQL编程与应用。 
<p></p>5、其他编程语言－其他嵌入式编程语言ada、VHDL等。 
<p></p><strong><font color="#0033ff">四、嵌入式高级技术</font></strong><p></p>1、内核分析－深入理解内核（嵌入式linux等），编译、移植、修改内核等 
<p></p>2、设备驱动程序开发－开发各种设备驱动程序，触摸屏、I/O接口等 
<p></p>3、嵌入式图形开发－GUI基础知识，建立Qt/Embedded 开发环境，编写qt程序 
<p></p>3、仿真软件－Skyeye嵌入式软件模拟仿真 
<p></p>4、开源项目－开源项目，大家互相交流 
<p></p><strong><font color="#0000ff">五、嵌入式操作系统</font></strong><p></p>1、嵌入式linux－ARM-linux，uClinux，RTlinux操作系统，gcc编译器，gdb调试器，Makefile详解， 
<p></p>2、vxwoks/wince－商业嵌入式操作系统 
<p></p>3、其他系统 
<p></p><strong><font color="#0000ff">六、嵌入式硬件平台</font></strong><p></p>1、ARM 
<p></p>2、DSP 
<p></p>3、其他硬件平台</div></div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50396.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-19 10:51 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/19/50396.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>s3c2410的Bootloader(Vivi)简介</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/18/50389.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 18 Oct 2008 14:14:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/18/50389.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50389.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/18/50389.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50389.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50389.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: s3c2410												的														Bootloader(Vivi)												源代码分析																										Bootloader(Vivi)												源代码分析																																		...&nbsp;&nbsp;<a href='http://www.cnitblog.com/guopingleee/archive/2008/10/18/50389.html'>阅读全文</a><img src ="http://www.cnitblog.com/guopingleee/aggbug/50389.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-18 22:14 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/18/50389.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>请教fflush的作用</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/13/50137.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 13 Oct 2008 02:56:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/13/50137.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50137.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/13/50137.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50137.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50137.html</trackback:ping><description><![CDATA[
		<table id="pid66763" cellspacing="0" cellpadding="0" summary="pid66763">
				<tbody>
						<tr>
								<td class="postcontent">
										<div class="postmessage defaultpost">
												<div id="ad_thread3_0">
												</div>
												<div id="ad_thread4_0">
												</div>
												<h2> </h2>
												<h2> </h2>
												<h2>请教fflush的作用</h2>
												<p>因为不会, 想不通. 所以一定要弄清, 做一个就要成一个. 一切都会成为过去. 明天的明天还在等我.<br /><br />源地址: <a href="http://bbs.bc-cn.net/thread-16519-1-1.html">http://bbs.bc-cn.net/thread-16519-1-1.html</a></p>
												<div class="t_msgfont" id="postmessage_66763">请问哪位可以帮我解释一下fflush(stdin)的作用，括号里面的stdin又是什么意思，程序里面不用这个又会怎么样？？？</div>
												<p class="posttags">搜索更多相关主题的帖子: <a href="http://bbs.bc-cn.net/tag-fflush.html" target="_blank">fflush</a><a href="http://bbs.bc-cn.net/tag-stdin.html" target="_blank">stdin</a><a href="http://bbs.bc-cn.net/tag-%C0%A8%BA%C5.html" target="_blank">括号</a></p>
												<div id="post_rate_div_66763">
												</div>
												<div style="MARGIN-TOP: 3px; OVERFLOW-X: hidden; WIDTH: 85%">
														<iframe marginwidth="0" marginheight="0" src="/ad/bbs_ad1.html" frameborder="0" width="468" scrolling="no" height="60">
														</iframe>
												</div>
										</div>
								</td>
						</tr>
						<tr>
								<td class="postauthor">
										<div class="popupmenu_popup userinfopanel" id="userinfo66763_menu" style="DISPLAY: none">
												<dl>UID：15304<br />阅读权限：10<br />性别：男<br />最后登录：2005-5-14<br /></dl>
												<p>
														<a href="http://bbs.bc-cn.net/space-uid-15304.html" target="_blank">查看详细资料</a>
												</p>
										</div>
								</td>
								<td class="postcontent">
										<div class="postactions">
												<p>
														<strong title="顶部" onclick="scroll(0,0)">TOP</strong>
												</p>
												<div id="ad_thread1_0">
												</div>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
		<div id="ad_interthread">
		</div>
		<div class="mainbox viewthread">
				<table id="pid66769" cellspacing="0" cellpadding="0" summary="pid66769">
						<tbody>
								<tr>
										<td class="postauthor">
												<cite>
														<a class="dropmenu" id="userinfo66769" onmouseover="showMenu(this.id)" href="http://bbs.bc-cn.net/space-uid-10478.html" target="_blank">yuki</a>
												</cite>
												<div class="avatar">
														<img src="http://pass.bccn.net/avatar.php?uid=10478&amp;size=" />
												</div>
												<p>
														<em>高级会员</em>
												</p>
												<p>
														<img alt="Rank: 4" src="http://bbs.bc-cn.net/images/default/star_level3.gif" />
												</p>
												<p class="profile">帖子：507<br />精华：<a href="http://bbs.bc-cn.net/digest.php?authorid=10478">11</a><br />积分：6310<br />威望：<font color="red"><b>5 </b></font><br />在线：297 小时<br />注册：2005-2-4<br /></p>
												<ul>
														<li class="space">
																<a href="http://hi.bccn.net/space.php?uid=10478" target="_blank">个人空间</a>
														</li>
														<li class="pm">
																<a onclick="pmwin('open', 'uid=10478')" href="http://bbs.bc-cn.net/thread-16519-1-1.html###">发短消息</a>
														</li>
														<li class="buddy">
																<a id="ajax_buddy_1" onclick="ajaxmenu(event, this.id, 3000, 0)" href="http://bbs.bc-cn.net/my.php?item=buddylist&amp;newbuddyid=10478&amp;buddysubmit=yes" target="_blank">加为好友</a>
														</li>
														<li class="offline">当前离线 </li>
												</ul>
										</td>
										<td class="postcontent">
												<div class="postinfo">
														<strong id="postnum66769" title="复制帖子链接到剪贴板" onclick="setcopy('http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1#pid66769', '帖子链接已经复制到剪贴板')">2<sup>#</sup></strong>
														<em onclick="$('postmessage_66769').className='t_bigfont'">大</em>
														<em onclick="$('postmessage_66769').className='t_msgfont'">中</em>
														<em onclick="$('postmessage_66769').className='t_smallfont'">小</em>发表于 2005-4-23 23:27 <a href="http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1&amp;authorid=10478" rel="nofollow">只看该作者</a></div>
												<div id="ad_thread2_1">
												</div>
												<div class="postmessage defaultpost">
														<div id="ad_thread3_1">
														</div>
														<div id="ad_thread4_1">
														</div>
														<div class="t_msgfont" id="postmessage_66769">清空输入的缓冲流，stdin是标准的输入设备，定义为文件指针。。可以视作文件一样输入。。。<br /><p align="right"><font color="#000066">[此贴子已经被作者于2005-4-23 23:28:32编辑过]</font></p><br /></div>
														<div id="post_rate_div_66769">
														</div>
												</div>
												<div class="signatures" style="HEIGHT: 39px; maxHeightIE: ">我们都在命运湖上荡舟划桨，波浪起伏使我们无法逃离孤行；如果我们迷失方向，波浪将指引我们穿过另一天曙光</div>
										</td>
								</tr>
								<tr>
										<td class="postauthor">
												<div class="popupmenu_popup userinfopanel" id="userinfo66769_menu" style="DISPLAY: none">
														<dl>UID：10478<br />阅读权限：50<br />性别：男<br />最后登录：2008-10-12<br /></dl>
														<p>
																<a href="http://bbs.bc-cn.net/space-uid-10478.html" target="_blank">查看详细资料</a>
														</p>
												</div>
										</td>
										<td class="postcontent">
												<div class="postactions">
														<p>
																<strong title="顶部" onclick="scroll(0,0)">TOP</strong>
														</p>
														<div id="ad_thread1_1">
														</div>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
		<div class="mainbox viewthread">
				<table id="pid66770" cellspacing="0" cellpadding="0" summary="pid66770">
						<tbody>
								<tr>
										<td class="postauthor">
												<cite>
														<a class="dropmenu" id="userinfo66770" onmouseover="showMenu(this.id)" href="http://bbs.bc-cn.net/space-uid-13594.html" target="_blank">musicml</a>
												</cite>
												<div class="avatar">
														<img src="http://pass.bccn.net/avatar.php?uid=13594&amp;size=" />
												</div>
												<p>
														<em>中级会员</em>
												</p>
												<p>
														<img alt="Rank: 3" src="http://bbs.bc-cn.net/images/default/star_level2.gif" />
														<img alt="Rank: 3" src="http://bbs.bc-cn.net/images/default/star_level1.gif" />
												</p>
												<p class="profile">帖子：273<br />精华：<a href="http://bbs.bc-cn.net/digest.php?authorid=13594">0</a><br />积分：2830<br />在线：0 小时<br />注册：2005-4-2<br /></p>
												<ul>
														<li class="space">
																<a href="http://hi.bccn.net/space.php?uid=13594" target="_blank">个人空间</a>
														</li>
														<li class="pm">
																<a onclick="pmwin('open', 'uid=13594')" href="http://bbs.bc-cn.net/thread-16519-1-1.html###">发短消息</a>
														</li>
														<li class="buddy">
																<a id="ajax_buddy_2" onclick="ajaxmenu(event, this.id, 3000, 0)" href="http://bbs.bc-cn.net/my.php?item=buddylist&amp;newbuddyid=13594&amp;buddysubmit=yes" target="_blank">加为好友</a>
														</li>
														<li class="offline">当前离线 </li>
												</ul>
										</td>
										<td class="postcontent">
												<div class="postinfo">
														<strong id="postnum66770" title="复制帖子链接到剪贴板" onclick="setcopy('http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1#pid66770', '帖子链接已经复制到剪贴板')">3<sup>#</sup></strong>
														<em onclick="$('postmessage_66770').className='t_bigfont'">大</em>
														<em onclick="$('postmessage_66770').className='t_msgfont'">中</em>
														<em onclick="$('postmessage_66770').className='t_smallfont'">小</em>发表于 2005-4-23 23:28 <a href="http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1&amp;authorid=13594" rel="nofollow">只看该作者</a></div>
												<div id="ad_thread2_2">
												</div>
												<div class="postmessage defaultpost">
														<div id="ad_thread3_2">
														</div>
														<div id="ad_thread4_2">
														</div>
														<div class="t_msgfont" id="postmessage_66770">清流函数！<br />stdin 代表标准输入</div>
														<div id="post_rate_div_66770">
														</div>
												</div>
												<div class="signatures" style="HEIGHT: 39px; maxHeightIE: ">Every thing is possible.</div>
										</td>
								</tr>
								<tr>
										<td class="postauthor">
												<div class="popupmenu_popup userinfopanel" id="userinfo66770_menu" style="DISPLAY: none">
														<dl>UID：13594<br />阅读权限：30<br />性别：男<br />最后登录：2007-5-18<br /></dl>
														<p>
																<a href="http://bbs.bc-cn.net/space-uid-13594.html" target="_blank">查看详细资料</a>
														</p>
												</div>
										</td>
										<td class="postcontent">
												<div class="postactions">
														<p>
																<strong title="顶部" onclick="scroll(0,0)">TOP</strong>
														</p>
														<div id="ad_thread1_2">
														</div>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
		<div class="mainbox viewthread">
				<table id="pid66771" cellspacing="0" cellpadding="0" summary="pid66771">
						<tbody>
								<tr>
										<td class="postauthor">
												<cite>
														<a class="dropmenu" id="userinfo66771" onmouseover="showMenu(this.id)" href="http://bbs.bc-cn.net/space-uid-15304.html" target="_blank">huangningbo</a>
												</cite>
												<div class="avatar">
														<img src="http://pass.bccn.net/avatar.php?uid=15304&amp;size=" />
												</div>
												<p>
														<em>新手上路</em>
												</p>
												<p>
														<img alt="Rank: 1" src="http://bbs.bc-cn.net/images/default/star_level1.gif" />
												</p>
												<p class="profile">帖子：5<br />精华：<a href="http://bbs.bc-cn.net/digest.php?authorid=15304">0</a><br />积分：150<br />在线：0 小时<br />注册：2005-4-23<br /></p>
												<ul>
														<li class="space">
																<a href="http://hi.bccn.net/space.php?uid=15304" target="_blank">个人空间</a>
														</li>
														<li class="pm">
																<a onclick="pmwin('open', 'uid=15304')" href="http://bbs.bc-cn.net/thread-16519-1-1.html###">发短消息</a>
														</li>
														<li class="buddy">
																<a id="ajax_buddy_3" onclick="ajaxmenu(event, this.id, 3000, 0)" href="http://bbs.bc-cn.net/my.php?item=buddylist&amp;newbuddyid=15304&amp;buddysubmit=yes" target="_blank">加为好友</a>
														</li>
														<li class="offline">当前离线 </li>
												</ul>
										</td>
										<td class="postcontent">
												<div class="postinfo">
														<strong id="postnum66771" title="复制帖子链接到剪贴板" onclick="setcopy('http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1#pid66771', '帖子链接已经复制到剪贴板')">4<sup>#</sup></strong>
														<em onclick="$('postmessage_66771').className='t_bigfont'">大</em>
														<em onclick="$('postmessage_66771').className='t_msgfont'">中</em>
														<em onclick="$('postmessage_66771').className='t_smallfont'">小</em>发表于 2005-4-23 23:30 <a href="http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1&amp;authorid=15304" rel="nofollow">只看该作者</a></div>
												<div id="ad_thread2_3">
												</div>
												<div class="postmessage defaultpost">
														<div id="ad_thread3_3">
														</div>
														<div id="ad_thread4_3">
														</div>
														<div class="t_msgfont" id="postmessage_66771">如果不用会怎么样，程序运行会不会不正常。</div>
														<div id="post_rate_div_66771">
														</div>
												</div>
										</td>
								</tr>
								<tr>
										<td class="postauthor">
												<div class="popupmenu_popup userinfopanel" id="userinfo66771_menu" style="DISPLAY: none">
														<dl>UID：15304<br />阅读权限：10<br />性别：男<br />最后登录：2005-5-14<br /></dl>
														<p>
																<a href="http://bbs.bc-cn.net/space-uid-15304.html" target="_blank">查看详细资料</a>
														</p>
												</div>
										</td>
										<td class="postcontent">
												<div class="postactions">
														<p>
																<strong title="顶部" onclick="scroll(0,0)">TOP</strong>
														</p>
														<div id="ad_thread1_3">
														</div>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
		<div class="mainbox viewthread">
				<table id="pid66772" cellspacing="0" cellpadding="0" summary="pid66772">
						<tbody>
								<tr>
										<td class="postauthor">
												<cite>
														<a class="dropmenu" id="userinfo66772" onmouseover="showMenu(this.id)" href="http://bbs.bc-cn.net/space-uid-10478.html" target="_blank">yuki</a>
												</cite>
												<div class="avatar">
														<img src="http://pass.bccn.net/avatar.php?uid=10478&amp;size=" />
												</div>
												<p>
														<em>高级会员</em>
												</p>
												<p>
														<img alt="Rank: 4" src="http://bbs.bc-cn.net/images/default/star_level3.gif" />
												</p>
												<p class="profile">帖子：507<br />精华：<a href="http://bbs.bc-cn.net/digest.php?authorid=10478">11</a><br />积分：6310<br />威望：<font color="red"><b>5 </b></font><br />在线：297 小时<br />注册：2005-2-4<br /></p>
												<ul>
														<li class="space">
																<a href="http://hi.bccn.net/space.php?uid=10478" target="_blank">个人空间</a>
														</li>
														<li class="pm">
																<a onclick="pmwin('open', 'uid=10478')" href="http://bbs.bc-cn.net/thread-16519-1-1.html###">发短消息</a>
														</li>
														<li class="buddy">
																<a id="ajax_buddy_4" onclick="ajaxmenu(event, this.id, 3000, 0)" href="http://bbs.bc-cn.net/my.php?item=buddylist&amp;newbuddyid=10478&amp;buddysubmit=yes" target="_blank">加为好友</a>
														</li>
														<li class="offline">当前离线 </li>
												</ul>
										</td>
										<td class="postcontent">
												<div class="postinfo">
														<strong id="postnum66772" title="复制帖子链接到剪贴板" onclick="setcopy('http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1#pid66772', '帖子链接已经复制到剪贴板')">5<sup>#</sup></strong>
														<em onclick="$('postmessage_66772').className='t_bigfont'">大</em>
														<em onclick="$('postmessage_66772').className='t_msgfont'">中</em>
														<em onclick="$('postmessage_66772').className='t_smallfont'">小</em>发表于 2005-4-23 23:38 <a href="http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1&amp;authorid=10478" rel="nofollow">只看该作者</a></div>
												<div id="ad_thread2_4">
												</div>
												<div class="postmessage defaultpost">
														<div id="ad_thread3_4">
														</div>
														<div id="ad_thread4_4">
														</div>
														<div class="t_msgfont" id="postmessage_66772">
																<p>#include &lt;stdio.h&gt; #include &lt;conio.h&gt;</p>
																<p>int main() { char a,b; printf("input a="); scanf("%c",&amp;a); if(a=='a') { /* fflush(stdin); */ printf("input b="); scanf("%c",&amp;b); if(b=='b') printf("ok\n"); } getch(); return 1; } 自己体会一下用和不用所带来的不同效果吧。。。。。。。。。。。</p>
																<img alt="" src="http://bbs.bc-cn.net/images/smilies/emot/em05.gif" border="0" smilieid="88" />
																<img alt="" src="http://bbs.bc-cn.net/images/smilies/emot/em05.gif" border="0" smilieid="88" />
																<img alt="" src="http://bbs.bc-cn.net/images/smilies/emot/em05.gif" border="0" smilieid="88" />
																<img alt="" src="http://bbs.bc-cn.net/images/smilies/emot/em05.gif" border="0" smilieid="88" />
																<img alt="" src="http://bbs.bc-cn.net/images/smilies/emot/em05.gif" border="0" smilieid="88" />
														</div>
														<div id="post_rate_div_66772">
														</div>
												</div>
												<div class="signatures" style="HEIGHT: 39px; maxHeightIE: ">我们都在命运湖上荡舟划桨，波浪起伏使我们无法逃离孤行；如果我们迷失方向，波浪将指引我们穿过另一天曙光</div>
										</td>
								</tr>
								<tr>
										<td class="postauthor">
												<div class="popupmenu_popup userinfopanel" id="userinfo66772_menu" style="DISPLAY: none">
														<dl>UID：10478<br />阅读权限：50<br />性别：男<br />最后登录：2008-10-12<br /></dl>
														<p>
																<a href="http://bbs.bc-cn.net/space-uid-10478.html" target="_blank">查看详细资料</a>
														</p>
												</div>
										</td>
										<td class="postcontent">
												<div class="postactions">
														<p>
																<strong title="顶部" onclick="scroll(0,0)">TOP</strong>
														</p>
														<div id="ad_thread1_4">
														</div>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
		<div class="mainbox viewthread">
				<table id="pid66781" cellspacing="0" cellpadding="0" summary="pid66781">
						<tbody>
								<tr>
										<td class="postauthor">
												<cite>
														<a class="dropmenu" id="userinfo66781" onmouseover="showMenu(this.id)" href="http://bbs.bc-cn.net/space-uid-15304.html" target="_blank">huangningbo</a>
												</cite>
												<div class="avatar">
														<img src="http://pass.bccn.net/avatar.php?uid=15304&amp;size=" />
												</div>
												<p>
														<em>新手上路</em>
												</p>
												<p>
														<img alt="Rank: 1" src="http://bbs.bc-cn.net/images/default/star_level1.gif" />
												</p>
												<p class="profile">帖子：5<br />精华：<a href="http://bbs.bc-cn.net/digest.php?authorid=15304">0</a><br />积分：150<br />在线：0 小时<br />注册：2005-4-23<br /></p>
												<ul>
														<li class="space">
																<a href="http://hi.bccn.net/space.php?uid=15304" target="_blank">个人空间</a>
														</li>
														<li class="pm">
																<a onclick="pmwin('open', 'uid=15304')" href="http://bbs.bc-cn.net/thread-16519-1-1.html###">发短消息</a>
														</li>
														<li class="buddy">
																<a id="ajax_buddy_5" onclick="ajaxmenu(event, this.id, 3000, 0)" href="http://bbs.bc-cn.net/my.php?item=buddylist&amp;newbuddyid=15304&amp;buddysubmit=yes" target="_blank">加为好友</a>
														</li>
														<li class="offline">当前离线 </li>
												</ul>
										</td>
										<td class="postcontent">
												<div class="postinfo">
														<strong id="postnum66781" title="复制帖子链接到剪贴板" onclick="setcopy('http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1#pid66781', '帖子链接已经复制到剪贴板')">6<sup>#</sup></strong>
														<em onclick="$('postmessage_66781').className='t_bigfont'">大</em>
														<em onclick="$('postmessage_66781').className='t_msgfont'">中</em>
														<em onclick="$('postmessage_66781').className='t_smallfont'">小</em>发表于 2005-4-23 23:51 <a href="http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1&amp;authorid=15304" rel="nofollow">只看该作者</a></div>
												<div id="ad_thread2_5">
												</div>
												<div class="postmessage defaultpost">
														<div id="ad_thread3_5">
														</div>
														<div id="ad_thread4_5">
														</div>
														<div class="t_msgfont" id="postmessage_66781">意思就是说如果不清空缓冲，再要输入数据的时候就会缓冲满了，就输不进去数据了，是不是？<br />第一次在这里发贴，这里的热心人真多，谢谢大家</div>
														<div id="post_rate_div_66781">
														</div>
												</div>
										</td>
								</tr>
								<tr>
										<td class="postauthor">
												<div class="popupmenu_popup userinfopanel" id="userinfo66781_menu" style="DISPLAY: none">
														<dl>UID：15304<br />阅读权限：10<br />性别：男<br />最后登录：2005-5-14<br /></dl>
														<p>
																<a href="http://bbs.bc-cn.net/space-uid-15304.html" target="_blank">查看详细资料</a>
														</p>
												</div>
										</td>
										<td class="postcontent">
												<div class="postactions">
														<p>
																<strong title="顶部" onclick="scroll(0,0)">TOP</strong>
														</p>
														<div id="ad_thread1_5">
														</div>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
		<div class="mainbox viewthread">
				<table id="pid66784" cellspacing="0" cellpadding="0" summary="pid66784">
						<tbody>
								<tr>
										<td class="postauthor">
												<cite>
														<a class="dropmenu" id="userinfo66784" onmouseover="showMenu(this.id)" href="http://bbs.bc-cn.net/space-uid-10478.html" target="_blank">yuki</a>
												</cite>
												<div class="avatar">
														<img src="http://pass.bccn.net/avatar.php?uid=10478&amp;size=" />
												</div>
												<p>
														<em>高级会员</em>
												</p>
												<p>
														<img alt="Rank: 4" src="http://bbs.bc-cn.net/images/default/star_level3.gif" />
												</p>
												<p class="profile">帖子：507<br />精华：<a href="http://bbs.bc-cn.net/digest.php?authorid=10478">11</a><br />积分：6310<br />威望：<font color="red"><b>5 </b></font><br />在线：297 小时<br />注册：2005-2-4<br /></p>
												<ul>
														<li class="space">
																<a href="http://hi.bccn.net/space.php?uid=10478" target="_blank">个人空间</a>
														</li>
														<li class="pm">
																<a onclick="pmwin('open', 'uid=10478')" href="http://bbs.bc-cn.net/thread-16519-1-1.html###">发短消息</a>
														</li>
														<li class="buddy">
																<a id="ajax_buddy_6" onclick="ajaxmenu(event, this.id, 3000, 0)" href="http://bbs.bc-cn.net/my.php?item=buddylist&amp;newbuddyid=10478&amp;buddysubmit=yes" target="_blank">加为好友</a>
														</li>
														<li class="offline">当前离线 </li>
												</ul>
										</td>
										<td class="postcontent">
												<div class="postinfo">
														<strong id="postnum66784" title="复制帖子链接到剪贴板" onclick="setcopy('http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1#pid66784', '帖子链接已经复制到剪贴板')">7<sup>#</sup></strong>
														<em onclick="$('postmessage_66784').className='t_bigfont'">大</em>
														<em onclick="$('postmessage_66784').className='t_msgfont'">中</em>
														<em onclick="$('postmessage_66784').className='t_smallfont'">小</em>发表于 2005-4-23 23:56 <a href="http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1&amp;authorid=10478" rel="nofollow">只看该作者</a></div>
												<div id="ad_thread2_6">
												</div>
												<div class="postmessage defaultpost">
														<div id="ad_thread3_6">
														</div>
														<div id="ad_thread4_6">
														</div>
														<div class="t_msgfont" id="postmessage_66784">
																<font style="BACKGROUND-COLOR: #d3d3d3">并不是那样，首先你注意我给出的源代码，第一scanf()接受一个字符输入，当你输入一个字符后按下回车，只有你输入的那个字符被赋给了a，而剩下的一个换行符还保留在缓冲中，当第二次输入时无论你输入的什么字符，都是无效的，缓冲就如堆栈，符合先进先出原则，既然你缓冲中先前有个换行符，那么系统在遇见第二个scanf时自动会将换行符赋给b，所以输入的东西都是无效的。。。。</font>
														</div>
														<div id="post_rate_div_66784">
																<font style="BACKGROUND-COLOR: #d3d3d3">
																</font>
														</div>
												</div>
												<div class="signatures" style="HEIGHT: 39px; maxHeightIE: ">
														<font style="BACKGROUND-COLOR: #d3d3d3">我们都在命运湖上荡舟划桨，波浪起伏使我们无法逃离孤行；如果我们迷失方向，波浪将指引我们穿过另一天曙光</font>
												</div>
										</td>
								</tr>
								<tr>
										<td class="postauthor">
												<div class="popupmenu_popup userinfopanel" id="userinfo66784_menu" style="DISPLAY: none">
														<dl>UID：10478<br />阅读权限：50<br />性别：男<br />最后登录：2008-10-12<br /></dl>
														<p>
																<a href="http://bbs.bc-cn.net/space-uid-10478.html" target="_blank">查看详细资料</a>
														</p>
												</div>
										</td>
										<td class="postcontent">
												<div class="postactions">
														<p>
																<strong title="顶部" onclick="scroll(0,0)">TOP</strong>
														</p>
														<div id="ad_thread1_6">
														</div>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
		<div class="mainbox viewthread">
				<table id="pid66787" cellspacing="0" cellpadding="0" summary="pid66787">
						<tbody>
								<tr>
										<td class="postauthor">
												<a name="lastpost">
												</a>
												<cite>
														<a class="dropmenu" id="userinfo66787" onmouseover="showMenu(this.id)" href="http://bbs.bc-cn.net/space-uid-15304.html" target="_blank">huangningbo</a>
												</cite>
												<div class="avatar">
														<img src="http://pass.bccn.net/avatar.php?uid=15304&amp;size=" />
												</div>
												<p>
														<em>新手</em>
												</p>
										</td>
										<td class="postcontent">
												<div class="postinfo">
														<strong id="postnum66787" title="复制帖子链接到剪贴板" onclick="setcopy('http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1#pid66787', '帖子链接已经复制到剪贴板')">8<sup>#</sup></strong>
														<em onclick="$('postmessage_66787').className='t_bigfont'">大</em>
														<em onclick="$('postmessage_66787').className='t_msgfont'">中</em>
														<em onclick="$('postmessage_66787').className='t_smallfont'">小</em>发表于 2005-4-24 00:06 <a href="http://bbs.bc-cn.net/viewthread.php?tid=16519&amp;page=1&amp;authorid=15304" rel="nofollow">只看该作者</a></div>
										</td>
								</tr>
						</tbody>
				</table>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50137.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-13 10:56 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/13/50137.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>信号量和互斥锁有什么区别？？</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/10/50048.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 10 Oct 2008 05:39:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/10/50048.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50048.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/10/50048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50048.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50048.html</trackback:ping><description><![CDATA[
		<h1>信号量和互斥锁有什么区别？？</h1>
		<div class="author">
				<a class="anchor" name="Top">楼主</a>hqy_79（蚯蚓）<input class="user1" title="一级用户 该版得分小于等于100分" type="button" />2005-07-07 14:47:35 在 Linux/Unix社区 / 程序开发区 提问</div>
		<p>我要锁住一个共享内存（shmctl）   <br />  用信号量(semctl)和互斥锁（pthread_mutex_lock）有什么区别呀？   <br />  <span>问题点数：20、回复次数：4</span><a href="http://topic.csdn.net/t/20050707/14/4129164.html#">Top</a></p>
		<div class="tagad">
				<iframe src="/Include/Board.htm?Tags=" frameborder="0" scrolling="no">
				</iframe>
		</div>
		<h3>
				<strong>
						<a class="anchor" name="r_30422814">1 楼</a>goodboy1881（积木)(谁都别拦着我在水源升星）<input class="star1" title="一星用户 该版得分小于等于10000分，大于5000分" type="button" /></strong>
				<span>回复于 2005-07-07 14:59:01 得分 <em>15</em></span>
		</h3>
		<p>
				<font style="BACKGROUND-COLOR: #ccff66">这是概念上的区别，   <br />  比如说，信号，那是多线程同步用的，一个线程完成了某一个动作就通过信号告诉别的线程，别的线程再进行某些动作。   <br />  互斥锁，这是多线程互斥用的，比如说，一个线程占用了某一个资源，那么别的线程就无法访问，知道这个线程离开，其他的线程才开始可以利用这个资源。   <br />  看你自己的用途，你说的这个，就用互斥锁就可以了，</font>   <br />    <br />  个人看法。<a href="http://topic.csdn.net/t/20050707/14/4129164.html#">Top</a></p>
		<h3>
				<strong>
						<a class="anchor" name="r_30427157">2 楼</a>ericzhangali（另一个空间）<input class="star1" title="一星用户 该版得分小于等于10000分，大于5000分" type="button" /></strong>
				<span>回复于 2005-07-07 17:40:22 得分 0 </span>
		</h3>
		<p>同步，互斥，在这里其实是一个意思。<a href="http://topic.csdn.net/t/20050707/14/4129164.html#">Top</a></p>
		<h3>
				<strong>
						<a class="anchor" name="r_30428745">3 楼</a>niuniu612（）<input class="user1" title="一级用户 该版得分小于等于100分" type="button" /></strong>
				<span>回复于 2005-07-07 19:29:22 得分 <em>5</em></span>
		</h3>
		<p>
				<br />  互斥锁是为上锁而优化，条件变量是为等待而优化的，信号灯即可用于上锁，也可用于等待，因而可能导致更多的开销和更高的复杂性-----摘自《unix网络编程之进程间通讯》192页<a href="http://topic.csdn.net/t/20050707/14/4129164.html#">Top</a></p>
		<h3>
				<strong>
						<a class="anchor" name="r_30487595">4 楼</a>hqy_79（蚯蚓）<input class="user1" title="一级用户 该版得分小于等于100分" type="button" /></strong>
				<span>回复于 2005-07-11 17:32:21 得分 0 </span>
		</h3>
		<p>看来我用互斥锁就可以了   <br />  谢谢大家   <br />  </p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/50048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-10 13:39 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/10/50048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(精)[原创]手把手教你Linux下的多线程设计－－Linux下多线程编程详解</title><link>http://www.cnitblog.com/guopingleee/archive/2008/10/10/50047.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 10 Oct 2008 05:02:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/10/10/50047.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/50047.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/10/10/50047.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/50047.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/50047.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: [原创]手把手教你Linux下的多线程设计－－Linux下多线程编程详解(一) 地址: http://blog.csdn.net/Frozen_fish/archive/2007/07/11/1685141.aspx  【原创】手把手教你Linux下的多线程设计(一)                                      －－Linux下多线程编程详解 原创作者：Frozen_...&nbsp;&nbsp;<a href='http://www.cnitblog.com/guopingleee/archive/2008/10/10/50047.html'>阅读全文</a><img src ="http://www.cnitblog.com/guopingleee/aggbug/50047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-10-10 13:02 <a href="http://www.cnitblog.com/guopingleee/archive/2008/10/10/50047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux初学者常用命令</title><link>http://www.cnitblog.com/guopingleee/archive/2008/09/24/49487.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Wed, 24 Sep 2008 01:50:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/09/24/49487.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/49487.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/09/24/49487.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/49487.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/49487.html</trackback:ping><description><![CDATA[
		<p>现在的Linux图形管理界面越来越强大了，但是还是有些操作用命令行更方便。<br />前几天老有人加我QQ问我一些很奇怪的问题，希望有想学习Linux的朋友可以系统的先看一些基本操作方式和常用的命令。至少不用去问别人一些感觉奇怪的问题，这就像一个刚学电脑的朋友问怎么开机一样。不会开机用什么电脑呢？<br />在网上找了一份完整一点的Linux初学者常用命令，希望能够帮助到想学习Linux的朋友。</p>
		<p>没必要全部都记住，又不是去做网管。稍微明白记住一点就够用了。<br />下载Linux命令PD<span class="hilite"><font style="BACKGROUND-COLOR: #99ccff">F</font></span>请<a href="http://www.box.net/shared/dipgh4kgk4"><font color="#0082d6">点击这里</font></a></p>
		<blockquote>
				<p>
						<font style="BACKGROUND-COLOR: #ee82ee">NO 分类 PS1 命令名 用法及参数 功能注解<br />1 文件管理 # ls ls -a 列出当前目录下的所有文件，包括以.头的隐含文件<br />文件管理 # ls ls -l或ll 列出当前目录下文件的详细信息<br />文件管理 # pwd pwd 查看当前所在目录的绝对路经<br />文件管理 # cd cd .. 回当前目录的上一级目录<br />文件管理 # cd cd - 回上一次所在的目录<br />文件管理 # cd cd ~ 或 cd 回当前用户的宿主目录<br />文件管理 # cd cd ~用户名 回指定用户的宿主目录<br />2 文件管理 # mkdir mkdir 目录名 创建一个目录<br />文件管理 # mkdir mkdir –p 递归式去创建一些嵌套目录<br />文件管理 # rmdir Rmdir 空目录名 删除一个空目录<br />3 文件管理 # rm rm 文件名 文件名 删除一个文件或多个文件<br />文件管理 # rm rm -rf 非空目录名 递归删除一个非空目录下的一切，不让提式-<span class="hilite">f</span><br />4 文件管理 # cat cat文件名 一屏查看文件内容<br />5 文件管理 # more more文件名 分页查看文件内容<br />6 文件管理 # less less 文件名 可控分页查看文件内容<br />7 文件管理 # grep grep字符 文件名 根据字符匹配来查看文件部分内容<br />8 文件管理 # mv mv 路经/文件 /经/文件 移动相对路经下的文件到绝对路经下<br />文件管理 # mv mv 文件名 新名称 在当前目录下改名<br />9 文件管理 # cp cp /路经/文件 ./ 移动绝对路经下的文件到当前目录下<br />10 文件管理 # find <span class="hilite">f</span>ind 路经 -name “字符串” 查找路经所在范围内满足字符串匹配的文件和目录<br />11 文件管理 # ln ln 源文件 链接名 创建当前目录源文件的硬链接<br />ln /home/test /usr/test1 在/usr下建立/home/test的硬链接<br />12 文件管理 # ln Ln -s a b 创建当前目录下a的符号链接b<br />13 文件管理 # touch touch file1 <span class="hilite">f</span>ile2 创建两个空文件<br />14 磁盘管理 # df d<span class="hilite">f</span> 用于报告文件系统的总容量，使用量，剩余容量。<br />15 磁盘管理 # du du -b /home 查看目前/HOME目录的容量(k)及子目录的容量(k)。<br />16 磁盘管理 # fdisk <span class="hilite">f</span>disk -l 查看系统分区信息<br />17 磁盘管理 # fdisk <span class="hilite">f</span>disk /dev/sdb 为一块新的SCSI硬盘进行分区<br />18 磁盘管理 # mkfs.ext3 Mk<span class="hilite">f</span>s.ext3 /dev/sdb1<br />为第一块SCSI硬盘的第一主分区格式化成<br />ext3的文件系统<br />mkfs.ext2 Mk<span class="hilite">f</span>s.ext2/dev/sdb2 格式化成ext2文件系统<br />19 磁盘管理 # mount mount -t 文件系统类型 设备路经 访问路经<br />磁盘管理 # 文件系统类型<br />Iso9660 光驱文件系统<br />vfat <span class="hilite">F</span>at文件系统(windows)<br />挂载光驱 # mount –t iso9660 /dev/cdrom /mnt/cdrom<br />挂载FAT # mount –t v<span class="hilite">f</span>at /dev/hda5 /mnt/cdrom 挂第一个ide的第五个逻辑分区<br />17 磁盘管理 # Umount /mnt/cdrom 卸载/mnt/cdrom为空<br />18 文件权限 # chmod chmod u+s file 为<span class="hilite">f</span>ile的属主加上特殊权限<br />chmod g+r file 为<span class="hilite">f</span>ile的属组加上读权限<br />chmod o+w file 为<span class="hilite">f</span>ile的其它用户加上写权限<br />chmod a-x file 为<span class="hilite">f</span>ile的所有用户减去执行权限<br />chmod 765 file 为<span class="hilite">f</span>ile的属主设为完全权限，属组设成读写权，其它用户具有读和执心权限<br />19 文件权限 # chown chown root /home 把/home的属主改成root用户<br />20 文件权限 # chgrp chgrp root /home 把/home的属组改成root组<br />21 打印管理 # redhat-con<span class="hilite">f</span>ig-printer-tui 进入安装打印机界面<br />22 打印管理 # lp lp –d hptr file 打印<span class="hilite">f</span>ile到hptr的打印机上<br />23 打印管理 # lpq Lpq –P 打印机名 查看打印机的状态<br />24 打印管理 # lprm Lprm –P 打印机名 a 删除打印机内的打印作业<br />25 打印管理 # disable Disable –r “changing paper” HPtr 禁用打印机并提示原因<br />26 打印管理 # enable Enable HPtr 重新启用被禁用的<br />27 用户管理 # useradd Useradd 创建一个新的用户<br />28 用户管理 # groupadd Groupadd 组名 创建一个新的组<br />29 用户管理 # passwd Passwd 用户名 为用户创建密码<br />30 用户管理 # Passwd -d Passwd -d用户名 删除用户密码也能登陆<br />31 用户管理 # Passwd -l Passwd -l用户名 锁定账号密码<br />32 用户管理 # Passwd -u Passwd -u用户名 解锁账号密码<br />33 用户管理 # Passwd -S Passwd -S用户名 查询账号密码<br />34 用户管理 # Usermod -l Usermod -l 新用户名 老用户名 为用户改名<br />35 用户管理 # Usermod -L Usermod -L 要锁定用户名 锁定用户登陆<br />36 用户管理 # Usermod -U Usermod –U解锁用户名 解锁用户登陆<br />37 用户管理 # Usermod -u Usermod –u 501用户名 改变用户UID<br />38 用户管理 # Userdel Userdel–r 用户名 删除用户一切<br />39 用户管理 # Groupmod -n Groupmod –n新用户名 老用户名 为组改名<br />40 用户管理 # Groupmod -g Groupmod –g 501 组名 改变组GID<br />41 用户管理 # groupdel Groupdel组名 先应删它的用户 删除组<br />42 用户管理 # gpasswd -a gpasswd -a 用户名 组名 增加用户到组<br />43 用户管理 # Id id 用户名 查用户信息<br />44 软件管理 # rpm -qa rpm –qa | less 查询已安装RPM<br />45 软件管理 # rpm –qa | grep <span class="hilite">f</span>tp 查询指定RPM<br />46 软件管理 # rpm -q rpm -q 已安装的RPM包 查是否安装<br />47 软件管理 # rpm -q telnet-server 查看telnet服务器包<br />48 软件管理 # rpm -qi rpm –qi 软件包名称 查看软件的描述信息<br />49 软件管理 # rpm -ql rpm –ql软件包名称 查询软件包的文件列表<br />50 软件管理 # rpm -qf rpm –q<span class="hilite">f</span>软件包名称 查询某个文件所属的软件包<br />51 软件管理 # rpm -qp rpm –qp软件包全名 查询未安装的软件包信息<br />52 软件管理 # rpm -e rpm –e 软件包名称 删除具体的软件包<br />53 软件管理 # rpm -U rpm –Uvh软件包全名 升级软件包并显示过程<br />54 软件管理 # rpm -ivh rpm –ivh 软件包全名 安装软件包并显示过程<br />55 软件管理 # rpm -V rpm –V软件包名称 验证软件包的大小，类型等<br />56 软件管理 # tar -c 创建包 –x 释放包 -v 显示命令过程 –z 代表压缩包<br />57 软件管理 # tar -cf tar –cv<span class="hilite">f</span> benet.tar /home/benet 把/home/benet目录打包<br />58 软件管理 # tar -czf tar –zcv<span class="hilite">f</span> benet.tar.gz /mnt 把目录打包并压缩<br />59 软件管理 # tar –tf tar –t<span class="hilite">f</span> benet.tar 看非压缩包的文件列表<br />60 软件管理 # tar –tzf tar –t<span class="hilite">f</span> benet.tar.gz 看压缩包的文件列表<br />61 软件管理 # tar –xf tar –x<span class="hilite">f</span> benet.tar 非压缩包的文件恢复<br />62 软件管理 # tar –zxvf tar –zxv<span class="hilite">f</span> benet.tar.gz 压缩包的文件解压恢复<br />63 软件管理 # tar -jxvf tar –jxv<span class="hilite">f</span> benet.tar.bz2<br />64 软件管理 # diff diff file1 <span class="hilite">f</span>ile2 &gt; 补丁名.patch 为新旧文件生成补丁文件<br />65 软件管理 # diff diff file1 <span class="hilite">f</span>ile2 比较两个文件的区别<br />66 软件管理 # Patch Patch <span class="hilite">f</span>ile补丁名.patch 打补丁<br />67 软件管理 # ./configure –pre<span class="hilite">f</span>ix=/usr/local/ 编译前配置<br />68 软件管理 # make 编译<br />69 软件管理 # make install 安装编译好的源码包<br />70 启动管理 # reboot Init 6 重启LINUX系统<br />71 启动管理 # Halt Init 0 Shutdown –h now 关闭LINUX系统<br />72 启动管理 # runlevel 显示系统运行级<br />73 启动管理 # Init [0123456] 改变系统运行级,7种<br />74 启动管理 # Chkcon<span class="hilite">f</span>ig –-list [服务名称] 查看服务的状态<br />75 启动管理 # Chkcon<span class="hilite">f</span>ig –-level &lt;运行级&gt; &lt;服务名&gt; on|of<span class="hilite">f</span>|set 设置服务的启动状态<br />76 启动管理 # Chkcon<span class="hilite">f</span>ig &lt;服务名&gt; on|of<span class="hilite">f</span>|set 设置非独立服务启状态<br />77 进程管理 # Top动态 Ps-aux静态 进程树pstree 查看系统进程<br />78 进程管理 # 程序名 &amp; 后台运行程序<br />79 进程管理 # <span class="hilite">f</span>g 把后台运行的进程调回前台<br />80 进程管理 # bg 把前台运行进程调到后台<br />81 进程管理 # renice Renice +1 180 把180号进程的优先级加1<br />82 进程管理 # kill Kill PID 终止某个PID进程<br />83 进程管理 # at at 5pm + 3 days<br />/bin/ls 指定三天后下午5:00执行/bin/ls<br />84 进程管理 # crontab Crontab -e 用VI的形式来编辑自动周期性任务<br />85 进程管理 # crontab Crontab -l 查看自动周期性任务<br />86 进程管理 # crontab Crontab -r 删除自动周期性任务<br />87 进程管理 # crond Service crond <start|stop|restart|status><br />马上启动自动周期性服务 Service crond &lt;启动|停止|重启|状态&gt; </start|stop|restart|status></font>
				</p>
				<p>
						<font style="BACKGROUND-COLOR: #ee82ee">实现磁盘配额 (注安装LINUX时建立/home分区）<br />目标：对用户zhao在/home目录上实现so<span class="hilite">f</span>t limit为5k,hard limit 为10k的磁盘配额<br />实现步骤：<br />1. 修改包含/home的行， #vi /etc/fstab， 改为：de<span class="hilite">f</span>aults,usrquota。也就是增加usrquota项。然后保存退出。<br />2、卸载/home目录 #umount /home<br />3. 挂接/home目录 #mount /home<br />4、增加用户zhao #useradd zhao<br />5、修改密码 #passwd zhao<br />6、生成关于/home目录的quota信息 # quotacheck -cmug /home<br />#quotacheck -vu /home<br />7、查看所有用户的信息 #repquota -au<br />8、设置配额 #edquota -u zhao<br />将so<span class="hilite">f</span>t 和hard 分别改为5和10<br />9、保存并退出 #wq!<br />10、修改时间 #edquota -t<br />11、 #wq!<br />12.开启/home上的磁盘配额功能 #quotaon /home<br />13.查询配额 #quota -u zhao<br />14.验证配额 #su - zhao<br />$touch my<span class="hilite">f</span>ile</font>
				</p>
		</blockquote>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/49487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-09-24 09:50 <a href="http://www.cnitblog.com/guopingleee/archive/2008/09/24/49487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 超用户下改密码 </title><link>http://www.cnitblog.com/guopingleee/archive/2008/09/24/49485.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Wed, 24 Sep 2008 01:10:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/09/24/49485.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/49485.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/09/24/49485.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/49485.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/49485.html</trackback:ping><description><![CDATA[1、重新启动机器，在出现grub引导界面后，按F2，在启动linux的选项里加上init=/bin/bash，通过给内核传递init=/bin/bash参数使得OS在运行login程序之前运行bash，出现命令行。<br /><br />2、稍等片刻出现(none)#:命令行。<br /><br />3、输入mount-n/-oremount,rw<br /><br />4、输入mount–n/usr<br /><br />5、输入cd/usr/bin<br /><br /><font style="BACKGROUND-COLOR: #ee82ee">6、输入passwd命令就可以重置密码了。输入新密码。<br /></font><br />7、修改完成后记得用mount-n/-oremount,ro将根文件系统置为原来的状态。<br /><br />8、输入exit退出系统，重新启动系统，用新密码登录。 <br /><br />SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码SUSE Linux下修改超级用户密码 <img src ="http://www.cnitblog.com/guopingleee/aggbug/49485.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-09-24 09:10 <a href="http://www.cnitblog.com/guopingleee/archive/2008/09/24/49485.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>snprintf/_snprintf 在不同平台间函数差异</title><link>http://www.cnitblog.com/guopingleee/archive/2008/09/18/49186.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Thu, 18 Sep 2008 01:23:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/09/18/49186.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/49186.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/09/18/49186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/49186.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/49186.html</trackback:ping><description><![CDATA[snprintf/_snprintf 在不同平台间函数差异
<div class="date">2007-11-20 17:25</div><table style="TABLE-LAYOUT: fixed"><tbody><tr><td><div class="cnt" id="blog_text"><strong><font style="BACKGROUND-COLOR: #ffff00">snprintf函数并不是标准c/c++中规定的函数，但是在许多编译器中，厂商提供了其实现的版本。<br />在gcc中，该函数名称就snprintf，而在VC中称为_snprintf。<br />　　由于不是标准函数，没有一个统一的标准来规定该函数的行为，所以导致了各厂商间的实现版本可<br />能会有差异。今天也的的确确看到了差异，因为这个小小的差异是我的程序无法正常的处理数据。<br />　　这个小小的差异发生在count参数。在VC中，这个count就是要写入的总字符串字符数，例如：</font><br />　　　　</strong><div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid"><div><strong><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #008000">//</span><span style="COLOR: #008000">VC</span></strong><span style="COLOR: #008000"><br /><strong><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></strong></span><strong><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> argc, </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"></span><span style="COLOR: #000000">*</span></strong><strong><span style="COLOR: #000000"> argv[])<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img style="DISPLAY: none" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span></strong><span><strong><span style="COLOR: #000000">{<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">   buff[</span><span style="COLOR: #000000">100</span></strong><strong><span style="COLOR: #000000">];<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />     printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,_snprintf(buff,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">1234567890ab</span><span style="COLOR: #000000">"</span></strong><strong><span style="COLOR: #000000">));<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />     printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s</span><span style="COLOR: #000000">"</span></strong><strong><span style="COLOR: #000000">,buff);<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"></span><span style="COLOR: #000000">0</span></strong><span style="COLOR: #000000"><strong>;<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</strong></span></span><span style="COLOR: #000000"><br /><strong><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /><br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></strong></span><strong><span style="COLOR: #008000">//</span><span style="COLOR: #008000">Linxu:gcc/g++</span></strong><span style="COLOR: #008000"><br /><strong><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></strong></span><strong><span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">&gt;</span></strong><span style="COLOR: #000000"><br /><strong><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></strong></span><strong><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> argc, </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"></span><span style="COLOR: #000000">*</span></strong><strong><span style="COLOR: #000000"> argv[])<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img style="DISPLAY: none" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">...</span></strong><span><strong><span style="COLOR: #000000">{<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">   buff[</span><span style="COLOR: #000000">100</span></strong><strong><span style="COLOR: #000000">];<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />     printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,snprintf(buff,</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">1234567890ab</span><span style="COLOR: #000000">"</span></strong><strong><span style="COLOR: #000000">));<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />     printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%s</span><span style="COLOR: #000000">"</span></strong><strong><span style="COLOR: #000000">,buff);<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"></span><span style="COLOR: #000000">0</span></strong><span style="COLOR: #000000"><strong>;<br /><img src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</strong></span></span></div></div><pre class="syntax"> vc程序的输出是：<br /> -1<br /> 1234567890@<br />gcc程序的输出是：<br /> 12<br /> 123456789<br />从输出结果可以知道：VC中的_snprintf的count参数表示，会向buff中写入count个字符，不包括'\0'字符，<br />并且不会在字符串末尾添加'\0'符，并且，如果字符串超过count，函数返回-1以标志可能导致的错误；gcc<br />中的snprintf函数的count参数表示，向buff中写入10个字符，包括'\0'字符，并且，返回实际的字符串长度，<br />例子中为12。</pre><pre class="syntax">　　如果不了解这些函数在各平台间的差异，也许我们的程序在移植过程中会变得很脆弱。我们应该小心各种各样<br />的陷阱。</pre><p></p><p><strong><font face="Courier New">下面是MSDN对_snprintf函数的解释：</font></strong></p><pre class="syntax"><strong>int _snprintf( char</strong> *<em><a class="synParam" href="http://writeblog.csdn.net/Editor/FCKeditor/editor/">buffer</a></em>, <strong>size_t</strong><em><a class="synParam" href="http://writeblog.csdn.net/Editor/FCKeditor/editor/">count</a></em>, <strong>const char</strong> *<em><a class="synParam" href="http://writeblog.csdn.net/Editor/FCKeditor/editor/">format</a></em> [, <em><a class="synParam" href="http://writeblog.csdn.net/Editor/FCKeditor/editor/">argument</a></em>] ...<strong> );</strong></pre><div class="reftip" style="VISIBILITY: hidden; OVERFLOW: visible; POSITION: absolute"></div><h4>Parameters</h4><dl><dt><em>buffer</em></dt><dd>Storage location for output 
</dd><dt><em>count</em></dt><dd>Maximum number of characters to store 
</dd><dt><em>format</em></dt><dd>Format-control string 
</dd><dt><em>argument</em></dt><dd>Optional arguments </dd></dl><h4>Libraries</h4><p>All versions of the C run-time libraries.</p><h4>Return Value</h4><p><strong>_snprintf</strong> returns the number of bytes stored in <em>buffer</em>, not counting the terminating null character. If the number of bytes required to store the data exceeds <em>count</em>, then <em>count</em> bytes of data are stored in <em>buffer</em> and a negative value is returned.</p><h4>Remarks</h4><p>The <strong>_snprintf</strong> function formats and stores count or fewer characters and values (including a terminating null character that is always appended unless count is zero or the formatted string length is greater than or equal to count characters) in buffer. Each <em>argument</em> (if any) is converted and output according to the corresponding format specification in <em>format</em>. The format consists of ordinary characters and has the same form and function as the <em>format</em> argument for <strong>printf</strong>. If copying occurs between strings that overlap, the behavior is undefined.</p></div></td></tr></tbody></table><img src ="http://www.cnitblog.com/guopingleee/aggbug/49186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-09-18 09:23 <a href="http://www.cnitblog.com/guopingleee/archive/2008/09/18/49186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>扫盲行动之：Linux常用命令简</title><link>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49166.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Wed, 17 Sep 2008 09:12:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49166.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/49166.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49166.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/49166.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/49166.html</trackback:ping><description><![CDATA[
		<h1 class="Article_tle">
				<font style="BACKGROUND-COLOR: #ff1493">扫盲行动之：Linux常用命令简</font>
		</h1>
		<div class="Ud_tle">
				<br />　　<font style="BACKGROUND-COLOR: #ffc0cb">su <br />　　su命令是最基本的命令之一，常用于不同用户间切换。例如，如果登录为 user1，要切换为user2，只要用如下命令： <br />　　$su user2 <br />　　然后系统提示输入user2口令，输入正确的口令之后就可以切换到user2。完成之后就可以用exit命令返回到user1。 <br />　　su命令的常见用法是变成根用户或超级用户。如果发出不带用户名的su命令 ，则系统提示输入根口令，输入之后则可切换为根用户。 <br />　　如果登录为根用户，则可以用su命令成为系统上任何用户而不需要口令。 <br />　　<br />　　pwd <br />　　pwd命令也是最常用最基本的命令之一，用于显示用户当前所在的目录。 <br />　　<br />　　cd <br />　　cd命令不仅显示当前状态，还改变当前状态，它的用发跟dos下的cd命令基本一致。 <br />　　cd ..可进入上一层目录 <br />　　cd -可进入上一个进入的目录 <br />　　cd ~可进入用户的home目录 <br />　　<br />　　ls <br />　　ls命令跟dos下的dir命令一样，用于显示当前目录的内容。 <br />　　如果想取得详细的信息，可用ls -l命令， 这样就可以显示目录内容的详细信息。 <br />　　如果目录下的文件太多，用一屏显示不了，可以用ls -l |more分屏显示 。 <br />　　<br />　　find <br />　　find命令用于查找文件。这个命令可以按文件名、建立或修改日期、所有者(通常是建立文件的用户)、文件长度或文件类型进行搜索。 <br />　　find命令的基本结构如下： <br />　　$find <br />　　其中指定从哪个目录开始搜索。指定搜索条件。表示找到文件怎么处理。一般来说，要用-print动作，显示 整个文件路径和名称。如果没有这个动作，则find命令进行所要搜索而不显示结果，等于白费劲。 <br />　　例如，要搜索系统上所有名称为ye的文件，可用如下命令： <br />　　$find / -name ye -print <br />　　这样就可以显示出系统上所有名称为ye的文件。 <br />　　<br />　　tar <br />　　tar最初用于建立磁带备份系统，目前广泛用于建立文件发布档案。可用如下方法建立tar档案： <br />　　$tar cvf <br />　　例如，如果要将当前目录中所有文件存档到ye.tar中，可用如下命令： <br />　　$tar cvf ye.tar *.* <br />　　要浏览档案内容，将c选项变成t。如果要浏览ye.tar档案中的内容，可用如下命令： <br />　　$tar tvf ye.tar <br />　　要取出档案内的内容，将c选项变成x。如果要将ye.tar档案中的内容取到当前目录中，可用如下命令： <br />　　$tar xvf ye.tar <br />　　<br />　　gzip <br />　　gzip命令用于压缩文件。 例如，如果要将ye.txt文件压缩，可用如下命令： <br />　　$gzip ye.txt <br />　　这样就可以压缩文件并在文件名后面加上gz扩展名，变成文件ye.txt.gz。 <br />　　解压缩文件可用gzip -d命令实现： <br />　　$gzip -d ye.txt.gz <br />　　这样就可以解压缩文件并删除gz扩展名。除此之外还可以用gunzip命令来解 压缩文件，效果跟用gzip -d命令一样。 <br />　　旧版的tar命令不压缩档案，可用gzip压缩。例如： <br />　　$tar cvf ye.tar *.txt <br />　　$gzip ye.tar <br />　　则可建立压缩档案ye.tar.gz。 <br />　　新版的tar可以直接访问和建立gzip压缩的tar档案，只要在tar命令中加上z 选项就可以了。例如： <br />　　$tar czvf ye.tar *.txt <br />　　生成压缩档案ye.tar.gz， <br />　　$tar tzvf ye.tar *.txt <br />　　显示压缩档案ye.tar.gz的内容，而 <br />　　$tar xzvf ye.tar *.txt <br />　　取出压缩档案ye.tar.gz的内容。 <br />　　<br />　　mkdir <br />　　这个命令很简单，跟dos的md命令用法几乎一样，用于建立目录。 <br />　　<br />　　cp <br />　　cp命令用于复制文件或目录。 <br />　　cp命令可以一次复制多个文件，例如： <br />　　$cp *.txt *.doc *.bak /home <br />　　将当前目录中扩展名为txt、doc和bak的文件全部复制到/home目录中。 <br />　　如果要复制整个目录及其所有子目录，可以用cp -R命令。 <br />　　<br />　　rm <br />　　rm命令用于删除文件或目录。 <br />　　rm命令会强制删除文件，如果想要在删除时提示确认，可用rm -i命令。 <br />　　如果要删除目录，可用rm -r命令。rm -r命令在删除目录时，每删除一个文件或目录都会显示提示，如果目录太大，响应每个提示是不现实的。这时可以用 rm -rf命令来强制删除目录，这样即使用了-i标志也当无效处理。 <br />　　<br />　　mv <br />　　mv命令用于移动文件和更名文件。例如： <br />　　$mv ye.txt /home <br />　　将当前目录下的ye.txt文件移动到/home目录下， <br />　　$mv ye.txt ye1.txt <br />　　将ye.txt文件改名为ye1.txt。 <br />　　类似于跟cp命令，mv命令也可以一次移动多个文件，在此不再赘叙。 <br />　　<br />　　reboot <br />　　重启命令，不必多说。 </font></div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/49166.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-09-17 17:12 <a href="http://www.cnitblog.com/guopingleee/archive/2008/09/17/49166.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>FTP 和FTPS 区别??</title><link>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49163.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Wed, 17 Sep 2008 08:07:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49163.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/49163.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49163.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/49163.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/49163.html</trackback:ping><description><![CDATA[
		<h1>如何区别FTPS与TLS？</h1>
		<div class="dots">作者: Michael Cobb, 　出处:TechTarget,　责任编辑: lvye,　 
<div class="posted"><font face="宋体">2006-03-17 11:25</font></div></div>
		<h5 style="PADDING-RIGHT: 8px; PADDING-LEFT: 8px; FONT-WEIGHT: normal; PADDING-BOTTOM: 8px; LINE-HEIGHT: 20px; PADDING-TOP: 8px">　<font style="BACKGROUND-COLOR: #ffff00">　FTPS是在安全套接层使用标准的FTP协议和指令的一种增强型TFP协议，为FTP协议和数据通道增加了SSL安全功能。FTPS也称作“FTP-SSL”和“FTP-over-SSL”。SSL是一个在客户机和具有SSL功能的服务器之间的安全连接中对数据进行加密和解密的协议。</font></h5>
		<div id="content">
				<div class="guanggao">
						<span id="contentAdv">
						</span>
				</div>FTPS是在<a class="bluekey" href="http://security.ctocio.com.cn/" target="_blank"><font color="#16387c">安全</font></a>套接层使用标准的FTP协议和指令的一种增强型TFP协议，为FTP协议和数据通道增加了SSL安全功能。FTPS也称作“FTP-SSL”和“FTP-over-SSL”。SSL是一个在客户机和具有SSL功能的<a class="bluekey" href="http://server.ctocio.com.cn/" target="_blank"><font color="#16387c">服务器</font></a>之间的安全连接中对数据进行加密和解密的协议。</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/49163.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-09-17 16:07 <a href="http://www.cnitblog.com/guopingleee/archive/2008/09/17/49163.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux 常用命令 </title><link>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49162.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Wed, 17 Sep 2008 07:54:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49162.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/49162.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/09/17/49162.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/49162.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/49162.html</trackback:ping><description><![CDATA[
		<p> </p>
		<p>
				<font style="BACKGROUND-COLOR: #ffff00">cd <br />　　cd命令不仅显示当前状态，还改变当前状态，它的用发跟dos下的cd命令基本一致。 <br />　　cd ..可进入上一层目录 <br />　　cd -可进入上一个进入的目录 <br />　　cd ~可进入用户的home目录</font>
				<br />　　 <br /><br /></p>
		<p>
				<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/">http://www.math.ecnu.edu.cn/~jypan/linux/command/</a>
				<br />
				<br />
				<br />
		</p>
		<table cellspacing="5" cellpadding="1" width="700" border="0">
				<tbody>
						<tr>
								<td class="td1">Linux 系统常用命令格式： </td>
						</tr>
						<tr>
								<td>
										<pre>    command  [option]  [argument1]  [argument2]  ...
</pre>
										<p class="p1">其中option以“-”开始，多个option可用一个“-”连起来，如“ls -l -a” 与“ls -la”的效果是一样的。根据命令的不同，参数分为可选的或必须的；所有的命令从标准输入接受输入，输出结果显示在标准输出，而错误信息则显示在标准错误输出设备。可使用重定向功能对这些设备进行重定向。 </p>
										<p>命令在正常执行结果后返回一个0值，如果命令出错可未完全完成，则返回一个非零值(在shell中可用变量$?查看)。 在shell script中可用此返回值作为控制逻辑的一部分。 </p>
								</td>
						</tr>
						<tr>
								<td class="td1">帮助命令: </td>
						</tr>
						<tr>
								<td class="td2">
										<pre>man  获取相关命令的帮助信息
     例如：man dir 可以获取关于dir的使用信息。

info  获取相关命令的详细使用方法
      例如：info info 可以获取如何使用info的详细信息。
</pre>
								</td>
						</tr>
						<tr>
								<td class="td1">文件操作：</td>
						</tr>
						<tr>
								<td>
										<pre>
												<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/cat.htm">cat</a>  显示文件内容和合并多个文件 
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#clear">clear</a>  清屏
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#chattr">chattr</a>  改变文件属性
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#chgrp">chgrp</a>  改变文件组权
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/chmod.htm">chmod</a>  改变文件或目录的权限
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/chown.htm">chown</a>  改变文件的属权
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#comm">comm</a>  比较两个已排过序的文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/cp.htm">cp</a>  将文件拷贝至另一文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/dd.htm">dd</a>  从指定文件读取数据写到指定文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#df">df</a>  报告磁盘空间使用情况
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/diff.htm">diff</a>  比较两个文本文件，列出行不同之处
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#du">du</a>  统计目录／文件所占磁盘空间的大小
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#file">file</a>  辨识文件类型
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/emacs.pdf">emacs</a>  功能强大的编辑环境        
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/find.htm">find</a>  搜索文件并执行指定操作(<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/find2.htm">find2</a>)
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/grep.htm">grep</a>  按给定模式搜索文件内容
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/head.htm">head</a>  显示指定文件的前若干行
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/less.htm">less</a>  按页显示文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/ln.htm">ln</a>  创建文件链接
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/locate.htm">locate</a>  查找符合条件的文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/more.htm">more</a>  在终端屏幕按帧显示文本文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/mv.htm">mv</a>  文件或目录的移动或更名
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#rm">rm/rmdir</a>  删除文件／目录
sed  利用script来处理文本文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#sort">sort</a>  对指定文件按行进行排序
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#tail">tail</a>  显示指定文件的最后部分
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#touch">touch</a>  创建文件
tr  转换字符
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/books/vim63manual.pdf">vi</a>  全屏编辑器
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#wc">wc</a>  显示指定文件中的行数，词数或字符数
which  在环境变量 $PATH 设置的目录里查找符合条件的文件
</pre>
								</td>
						</tr>
						<tr>
								<td class="td1">压缩与备份:</td>
						</tr>
						<tr>
								<td>
										<pre>bzip2/bunzip2  .bz2文件的压缩/解压缩程序
cpio  备份文件
dump  备份文件系统
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/gzip.htm">gzip/gunzip</a>  .gz文件的压缩/解压缩程序
gzexe  压缩可执行文件
restore 还原由倾倒(Dump)操作所备份下来的文件或整个文件系统(一个分区)
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#tar">tar</a>  将若干文件存档或读取存档文件
unarj  解压缩.arj文件
zip/unzip  压缩/解压缩 zip文件
zipinfo  列出zip压缩文件的详细信息
</pre>
								</td>
						</tr>
						<tr>
								<td class="td1">磁盘操作:</td>
						</tr>
						<tr>
								<td>
										<pre>
												<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/cd_pwd.htm">cd/pwd</a>  切换目录/显示当前工作目录
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#df">df</a>  显示磁盘的相关信息
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#du">du</a>  显示目录或文件的大小
e2fsck  检查ext2/ext3文件系统的正确性
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#fdisk">fdisk</a>  对硬盘进行分区	
fsck  检查文件系统并尝试修复错误
losetup  设置循环设备
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/ls.htm">ls</a>  列出目录内容
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/mkdir.htm">mkdir</a>  创建目录
mformat  对MS-DOS文件系统的磁盘进行格式化
mkbootdisk  建立目前系统的启动盘
mke2fs  建立ext2文件系统
mkisofs  制作iso光盘映像文件
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/mount.htm">mount/umount</a> 加载文件系统/卸载文件系统
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#quota">quota</a>  显示磁盘已使用的空间与限制
sync  将内存缓冲区内的数据写入磁盘
tree  以树状图列出目录的内容
</pre>
								</td>
						</tr>
						<tr>
								<td class="td1">系统操作:</td>
						</tr>
						<tr>
								<td>
										<pre>
												<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#alias">alias</a>  设置指令的别名
chkconfig  检查，设置系统的各种服务
clock  调整 RTC 时间
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#date">date</a>  显示或设置系统时间与日期
dmesg  显示开机信息
eval  重新运算求出参数的内容
exit  退出目前的shell
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#export">export</a>  设置或显示环境变量
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#finger">finger</a>  查找并显示用户信息
free  显示内存状态
hostid  显示主机标识
hostname  显示主机名
id  显示用户标识
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#kill">kill</a>  删除执行中的程序或工作
last  列出目前与过去登入系统的用户相关信息
logout  退出系统
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#lsmod">lsmod</a>  显示已载入系统的模块
modprobe  自动处理可载入模块
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#passwd">passwd</a>  设置用户密码
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#ps">ps</a>  process status 报告程序状况
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#reboot">reboot</a>  重启计算机
rhwo  查看系统用户
rlogin  远程登入
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/rpm.htm">rpm</a>  管理Linux各项套件的程序
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#shutdown">shutdown</a>  关机 
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#su">su</a> switch user 变更用户身份
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#top">top</a>  显示，管理执行中的程序
uname  显示系统信息
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/useradd_del.htm">useradd/userdel</a>	 添加用户 / 删除用户
userinfo  图形界面的修改工具
usermod  修改用户属性，包括用户的shell类型，用户组等，甚至还能改登录名
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#w">w</a>  显示目前注册的用户及用户正运行的命令
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#whereis">whereis</a>	 确定一个命令的二进制执行码，源码及帮助所在的位置
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#who">who</a>  列出正在使用系统的用户
whois  查找并显示用户信息
</pre>
								</td>
						</tr>
						<tr>
								<td class="td1">网络通信:</td>
						</tr>
						<tr>
								<td>
										<pre>
												<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/arp.htm">arp</a>  网地址的显示及控制
ftp  文件传输
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/lftp.htm">lftp</a>  文件传输
mail  发送／接收电子邮件
mesg  允许或拒绝其他用户向自己所用的终端发送信息
mutt  E-mail管理程序
ncftp  文件传输
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#netstat">netstat</a>  显示网络连接、路由表和网络接口信息
pine  收发电子邮件，浏览新闻组
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/other.htm#ping">ping</a>  向网络上的主机发送 icmp echo request 包
ssh  安全模式下的远程登录
telnet  远程登录
talk  与另一用户对话
traceroute  显示到达某一主机所经由的路径及所使用的时间
<a href="http://www.math.ecnu.edu.cn/~jypan/linux/command/wget.htm">wget</a> 从网络上自动下载文件
write  向其他用户的终端写信息
</pre>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/49162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-09-17 15:54 <a href="http://www.cnitblog.com/guopingleee/archive/2008/09/17/49162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Linux中创建静态库和动态库 【转】</title><link>http://www.cnitblog.com/guopingleee/archive/2008/01/18/39009.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 18 Jan 2008 02:34:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2008/01/18/39009.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/39009.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2008/01/18/39009.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/39009.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/39009.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<a class="postTitle2" id="viewpost1_TitleUrl" href="http://www.cppblog.com/true/archive/2007/04/04/21256.html">
						<font color="#1a8bc8">在Linux中创建静态库和动态库 【转】</font>
				</a>
		</div>
		<p style="TEXT-INDENT: 20pt">我们通常把一些公用函数制作成函数库，供其它程序使用。函数库分为静态库和动态库两种。静态库在程序编译时会被连接到目标代码中，程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中，而是在程序运行是才被载入，因此在程序运行时还需要动态库存在。本文主要通过举例来说明在Linux中如何创建静态库和动态库，以及使用它们。 </p>
		<p style="TEXT-INDENT: 20pt">在创建函数库前，我们先来准备举例用的源程序，并将函数库的源程序编译成.o文件。 </p>
		<p style="TEXT-INDENT: 20pt">第1步：编辑得到举例的程序--hello.h、hello.c和main.c； </p>
		<p style="TEXT-INDENT: 20pt">hello.c(见程序2)是函数库的源程序，其中包含公用函数hello，该函数将在屏幕上输出"Hello XXX!"。hello.h(见程序1)为该函数库的头文件。main.c(见程序3)为测试库文件的主程序，在主程序中调用了公用函数hello。 </p> #ifndef HELLO_H<br /> #define HELLO_H<br /> <br /> void hello(const char *name);<br /> <br /> #endif //HELLO_H<br /> 程序1: hello.h<br /> <br /> #include &lt;stdio.h&gt;<br /> <br /> void hello(const char *name)<br /> {<br />  printf("Hello %s!\n", name);<br /> }<br /> 程序2: hello.c<br /> <br /> #include "hello.h"<br /> <br /> int main()<br /> {<br />  hello("everyone");<br />  return 0;<br /> }<br /> 程序3: main.c<br /><p style="TEXT-INDENT: 20pt">第2步：将hello.c编译成.o文件； </p><p style="TEXT-INDENT: 20pt">无论静态库，还是动态库，都是由.o文件创建的。因此，我们必须将源程序hello.c通过gcc先编译成.o文件。 </p><p style="TEXT-INDENT: 20pt">在系统提示符下键入以下命令得到hello.o文件。 </p><p style="TEXT-INDENT: 40pt"># gcc -c hello.c </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">(注1：本文不介绍各命令使用和其参数功能，若希望详细了解它们，请参考其他文档。) </p><p style="TEXT-INDENT: 20pt">(注2：首字符"#"是系统提示符，不需要键入，下文相同。) </p><p style="TEXT-INDENT: 20pt">我们运行ls命令看看是否生存了hello.o文件。 </p><p style="TEXT-INDENT: 40pt"># ls </p><p style="TEXT-INDENT: 40pt">hello.c hello.h hello.o main.c </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">(注3：首字符不是"#"为系统运行结果，下文相同。) </p><p style="TEXT-INDENT: 20pt">在ls命令结果中，我们看到了hello.o文件，本步操作完成。 </p><p style="TEXT-INDENT: 20pt">下面我们先来看看如何创建静态库，以及使用它。 </p><p style="TEXT-INDENT: 20pt">第3步：由.o文件创建静态库； </p><p style="TEXT-INDENT: 20pt">静态库文件名的命名规范是以lib为前缀，紧接着跟静态库名，扩展名为.a。例如：我们将创建的静态库名为myhello，则静态库文件名就是libmyhello.a。在创建和使用静态库时，需要注意这点。创建静态库用ar命令。 </p><p style="TEXT-INDENT: 20pt">在系统提示符下键入以下命令将创建静态库文件libmyhello.a。 </p><p style="TEXT-INDENT: 40pt"># ar cr libmyhello.a hello.o </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">我们同样运行ls命令查看结果： </p><p style="TEXT-INDENT: 40pt"># ls </p><p style="TEXT-INDENT: 40pt">hello.c hello.h hello.o libmyhello.a main.c </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">ls命令结果中有libmyhello.a。 </p><p style="TEXT-INDENT: 20pt">第4步：在程序中使用静态库； </p><p style="TEXT-INDENT: 20pt">静态库制作完了，如何使用它内部的函数呢？只需要在使用到这些公用函数的源程序中包含这些公用函数的原型声明，然后在用gcc命令生成目标文件时指明静态库名，gcc将会从静态库中将公用函数连接到目标文件中。注意，gcc会在静态库名前加上前缀lib，然后追加扩展名.a得到的静态库文件名来查找静态库文件。 </p><p style="TEXT-INDENT: 20pt">在程序3:main.c中，我们包含了静态库的头文件hello.h，然后在主程序main中直接调用公用函数hello。下面先生成目标程序hello，然后运行hello程序看看结果如何。 </p><p style="TEXT-INDENT: 40pt"># gcc -o hello main.c -L. -lmyhello </p><p style="TEXT-INDENT: 40pt"># ./hello </p><p style="TEXT-INDENT: 40pt">Hello everyone! </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">我们删除静态库文件试试公用函数hello是否真的连接到目标文件 hello中了。 </p><p style="TEXT-INDENT: 40pt"># rm libmyhello.a </p><p style="TEXT-INDENT: 40pt">rm: remove regular file `libmyhello.a'? y </p><p style="TEXT-INDENT: 40pt"># ./hello </p><p style="TEXT-INDENT: 40pt">Hello everyone! </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">程序照常运行，静态库中的公用函数已经连接到目标文件中了。 </p><p style="TEXT-INDENT: 20pt">我们继续看看如何在Linux中创建动态库。我们还是从.o文件开始。 </p><p style="TEXT-INDENT: 20pt">第5步：由.o文件创建动态库文件； </p><p style="TEXT-INDENT: 20pt">动态库文件名命名规范和静态库文件名命名规范类似，也是在动态库名增加前缀lib，但其文件扩展名为.so。例如：我们将创建的动态库名为myhello，则动态库文件名就是libmyhello.so。用gcc来创建动态库。 </p><p style="TEXT-INDENT: 20pt">在系统提示符下键入以下命令得到动态库文件libmyhello.so。 </p><p style="TEXT-INDENT: 40pt"># gcc -shared -fPCI -o libmyhello.so hello.o </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">我们照样使用ls命令看看动态库文件是否生成。 </p><p style="TEXT-INDENT: 40pt"># ls </p><p style="TEXT-INDENT: 40pt">hello.c hello.h hello.o libmyhello.so main.c </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">第6步：在程序中使用动态库； </p><p style="TEXT-INDENT: 20pt">在程序中使用动态库和使用静态库完全一样，也是在使用到这些公用函数的源程序中包含这些公用函数的原型声明，然后在用gcc命令生成目标文件时指明动态库名进行编译。我们先运行gcc命令生成目标文件，再运行它看看结果。 </p><p style="TEXT-INDENT: 40pt"># gcc -o hello main.c -L. -lmyhello </p><p style="TEXT-INDENT: 40pt"># ./hello </p><p style="TEXT-INDENT: 40pt">./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">哦！出错了。快看看错误提示，原来是找不到动态库文件libmyhello.so。程序在运行时，会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到，则载入动态库，否则将提示类似上述错误而终止程序运行。我们将文件libmyhello.so复制到目录/usr/lib中，再试试。 </p><p style="TEXT-INDENT: 40pt"># mv libmyhello.so /usr/lib </p><p style="TEXT-INDENT: 40pt"># ./hello </p><p style="TEXT-INDENT: 40pt">Hello everyone! </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">成功了。这也进一步说明了动态库在程序运行时是需要的。 </p><p style="TEXT-INDENT: 20pt">我们回过头看看，发现使用静态库和使用动态库编译成目标程序使用的gcc命令完全一样，那当静态库和动态库同名时，gcc命令会使用哪个库文件呢？抱着对问题必究到底的心情，来试试看。 </p><p style="TEXT-INDENT: 20pt">先删除除.c和.h外的所有文件，恢复成我们刚刚编辑完举例程序状态。 </p><p style="TEXT-INDENT: 40pt"># rm -f hello hello.o /usr/lib/libmyhello.so </p><p style="TEXT-INDENT: 40pt"># ls </p><p style="TEXT-INDENT: 40pt">hello.c hello.h main.c </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">在来创建静态库文件libmyhello.a和动态库文件libmyhello.so。 </p><p style="TEXT-INDENT: 40pt"># gcc -c hello.c </p><p style="TEXT-INDENT: 40pt"># ar cr libmyhello.a hello.o </p><p style="TEXT-INDENT: 40pt"># gcc -shared -fPCI -o libmyhello.so hello.o </p><p style="TEXT-INDENT: 40pt"># ls </p><p style="TEXT-INDENT: 40pt">hello.c hello.h hello.o libmyhello.a libmyhello.so main.c </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">通过上述最后一条ls命令，可以发现静态库文件libmyhello.a和动态库文件libmyhello.so都已经生成，并都在当前目录中。然后，我们运行gcc命令来使用函数库myhello生成目标文件hello，并运行程序 hello。 </p><p style="TEXT-INDENT: 40pt"># gcc -o hello main.c -L. -lmyhello </p><p style="TEXT-INDENT: 40pt"># ./hello </p><p style="TEXT-INDENT: 40pt">./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory </p><p style="TEXT-INDENT: 40pt"># </p><p style="TEXT-INDENT: 20pt">从程序hello运行的结果中很容易知道，当静态库和动态库同名时， gcc命令将优先使用动态库。 </p><img src ="http://www.cnitblog.com/guopingleee/aggbug/39009.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2008-01-18 10:34 <a href="http://www.cnitblog.com/guopingleee/archive/2008/01/18/39009.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用GDB调试程序</title><link>http://www.cnitblog.com/guopingleee/archive/2007/12/29/38245.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 29 Dec 2007 07:42:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2007/12/29/38245.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/38245.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2007/12/29/38245.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/38245.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/38245.html</trackback:ping><description><![CDATA[
		<p> 用GDB调试程序 <br />GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于，其可以形成执行序<br />列，形成脚本。UNIX下的软件全是命令行的，这给程序开发提代供了极大的便利，命令行<br />软件的优势在于，它们可以非常容易的集成在一起，使用几个简单的已有工具的命令，就可<br />以做出一个非常强大的功能。 <br />于是UNIX下的软件比Windows下的软件更能有机地结合，各自发挥各自的长处，组合成<br />更为强劲的功能。而Windows下的图形软件基本上是各自为营，互相不能调用，很不利于<br />各种软件的相互集成。在这里并不是要和Windows做个什么比较，所谓“寸有所长，尺有<br />所短”，图形化工具还是有不如命令行的地方。 <br />用GDB调试程序 <br />GDB概述 <br />———— <br />GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许，各位比较喜欢那<br />种图形界面方式的，像VC、BCB等IDE的调试，但如果你是在UNIX平台下做软件，你<br />会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长，<br />尺有所短”就是这个道理。 <br />一般来说，GDB主要帮忙你完成下面四个方面的功能： <br />1、启动你的程序，可以按照你的自定义的要求随心所欲的运行程序。 <br />2、可让被调试的程序在你所指定的调置的断点处停住。（断点可以是条件表达式） <br />3、当程序被停住时，可以检查此时你的程序中所发生的事。 <br />4、动态的改变你程序的执行环境。 <br />从上面看来，GDB和一般的调试工具没有什么两样，基本上也是完成这些功能，不过在细<br />节上，你会发现GDB这个调试工具的强大，大家可能比较习惯了图形化的调试工具，但有<br />时候，命令行的调试工具却有着图形化工具所不能完成的功能。让我们一一看来。 <br />一个调试示例 <br />—————— <br />源程序：tst.c <br />1 #include <br />2 <br />3 int func(int n) <br />4 { <br />5 int sum=0,i; <br />6 for(i=0; i&lt;7; i++) { </p>
		<p>8 sum+=i; <br />9 } <br />10 return sum; <br />11 } <br />12 <br />13 <br />14 main() <br />15 { <br />16 int i; <br />17 long result = 0; <br />18 for(i=1; i&lt;=100; i++) <br />19 { <br />20 result += i; <br />21 } <br />22 <br />23 printf("result[1-100] = %d \n", result ); <br />24 printf("result[1-250] = %d \n", func(250) ); <br />25 } <br />编译生成执行文件：（Linux下） <br />hchen/test&gt; cc -g tst.c -o tst <br />使用GDB调试： <br />hchen/test&gt; gdb tst &lt;---------- 启动GDB <br />GNU gdb 5.1.1 <br />Copyright 2002 Free Software Foundation, Inc. <br />GDB is free software, covered by the GNU General Public License, and you are <br />welcome to change it and/or distribute copies of it under certain conditions. <br />Type "show copying" to see the conditions. <br />There is absolutely no warranty for GDB. Type "show warranty" for details. <br />This GDB was configured as "i386-suse-linux"... <br />(gdb) l &lt;-------------------- l命令相当于list，从第一行开始例出原码。 <br />1 #include <br />2 <br />3 int func(int n) <br />4 { <br />5 int sum=0,i; <br />6 for(i=0; i 7 { <br />8 sum+=i; <br />9 } <br />10 return sum; <br />(gdb) &lt;-------------------- 直接回车表示，重复上一次命令 <br />11 } </p>
		<p>12 <br />13 <br />14 main() <br />15 { <br />16 int i; <br />17 long result = 0; <br />18 for(i=1; i&lt;=100; i++) <br />19 { <br />20 result += i; <br />(gdb) break 16 &lt;-------------------- 设置断点，在源程序第16行处。 <br />Breakpoint 1 at 0x8048496: file tst.c, line 16. <br />(gdb) break func &lt;-------------------- 设置断点，在函数func()入口处。 <br />Breakpoint 2 at 0x8048456: file tst.c, line 5. <br />(gdb) info break &lt;-------------------- 查看断点信息。 <br />Num Type Disp Enb Address What <br />1 breakpoint keep y 0x08048496 in main at tst.c:16 <br />2 breakpoint keep y 0x08048456 in func at tst.c:5 <br />(gdb) r &lt;--------------------- 运行程序，run命令简写 <br />Starting program: /home/hchen/test/tst <br />Breakpoint 1, main () at tst.c:17 &lt;---------- 在断点处停住。 <br />17 long result = 0; <br />(gdb) n &lt;--------------------- 单条语句执行，next命令简写。 <br />18 for(i=1; i&lt;=100; i++) <br />(gdb) n <br />20 result += i; <br />(gdb) n <br />18 for(i=1; i&lt;=100; i++) <br />(gdb) n <br />20 result += i; <br />(gdb) c &lt;--------------------- 继续运行程序，continue命令简写。 <br />Continuing. <br />result[1-100] = 5050 &lt;----------程序输出。 <br />Breakpoint 2, func (n=250) at tst.c:5 <br />5 int sum=0,i; <br />(gdb) n <br />6 for(i=1; i&lt;=n; i++) <br />(gdb) p i &lt;--------------------- 打印变量i的值，print命令简写。 <br />$1 = 134513808 <br />(gdb) n <br />8 sum+=i; <br />(gdb) n <br />6 for(i=1; i&lt;=n; i++) </p>
		<p>(gdb) p sum <br />$2 = 1 <br />(gdb) n <br />8 sum+=i; <br />(gdb) p i <br />$3 = 2 <br />(gdb) n <br />6 for(i=1; i&lt;=n; i++) <br />(gdb) p sum <br />$4 = 3 <br />(gdb) bt &lt;--------------------- 查看函数堆栈。 <br />#0 func (n=250) at tst.c:5 <br />#1 0x080484e4 in main () at tst.c:24 <br />#2 0x400409ed in __libc_start_main () from /lib/libc.so.6 <br />(gdb) finish &lt;--------------------- 退出函数。 <br />Run till exit from #0 func (n=250) at tst.c:5 <br />0x080484e4 in main () at tst.c:24 <br />24 printf("result[1-250] = %d \n", func(250) ); <br />Value returned is $6 = 31375 <br />(gdb) c &lt;--------------------- 继续运行。 <br />Continuing. <br />result[1-250] = 31375 &lt;----------程序输出。 <br />Program exited with code 027. &lt;--------程序退出，调试结束。 <br />(gdb) q &lt;--------------------- 退出gdb。 <br />hchen/test&gt; <br />好了，有了以上的感性认识，还是让我们来系统地认识一下gdb吧。 <br />使用GDB <br />———— <br />一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序，首先在编译时，我们必<br />须要把调试信息加到可执行文件中。使用编译器（cc/gcc/g++）的 -g 参数可以做到这一点。<br />如： <br />&gt; cc -g hello.c -o hello <br />&gt; g++ -g hello.cpp -o hello <br />如果没有-g，你将看不见程序的函数名、变量名，所代替的全是运行时的内存地址。当你用<br />-g把调试信息加入之后，并成功编译目标代码以后，让我们来看看如何用gdb来调试他。 <br />启动GDB的方法有以下几种： </p>
		<p>1、gdb <br />program也就是你的执行文件，一般在当然目录下。 <br />2、gdb core <br />用gdb同时调试一个运行程序和core文件，core是程序非法执行后core dump后产生的文件。 <br />3、gdb <br />如果你的程序是一个服务程序，那么你可以指定这个服务程序运行时的进程ID。gdb会自<br />动attach上去，并调试他。program应该在PATH环境变量中搜索得到。 <br />GDB启动时，可以加上一些GDB的启动开关，详细的开关可以用gdb -help查看。我在下<br />面只例举一些比较常用的参数： <br />-symbols <br />-s <br />从指定文件中读取符号表。 <br />-se file <br />从指定文件中读取符号表信息，并把他用在可执行文件中。 <br />-core <br />-c <br />调试时core dump的core文件。 <br />-directory <br />-d <br />加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。 <br />GDB的命令概貌 <br />——————— <br />启动gdb后，就你被带入gdb的调试环境中，就可以使用gdb的命令开始调试程序了，gdb<br />的命令可以使用help命令来查看，如下所示： <br />/home/hchen&gt; gdb <br />GNU gdb 5.1.1 <br />Copyright 2002 Free Software Foundation, Inc. <br />GDB is free software, covered by the GNU General Public License, and you are <br />welcome to change it and/or distribute copies of it under certain conditions. <br />Type "show copying" to see the conditions. <br />There is absolutely no warranty for GDB. Type "show warranty" for details. <br />This GDB was configured as "i386-suse-linux". <br />(gdb) help </p>
		<p>List of classes of commands: <br />aliases -- Aliases of other commands <br />breakpoints -- Making program stop at certain points <br />data -- Examining data <br />files -- Specifying and examining files <br />internals -- Maintenance commands <br />obscure -- Obscure features <br />running -- Running the program <br />stack -- Examining the stack <br />status -- Status inquiries <br />support -- Support facilities <br />tracepoints -- Tracing of program execution without stopping the program <br />user-defined -- User-defined commands <br />Type "help" followed by a class name for a list of commands in that class. <br />Type "help" followed by command name for full documentation. <br />Command name abbreviations are allowed if unambiguous. <br />(gdb) <br />gdb的命令很多，gdb把之分成许多个种类。help命令只是例出gdb的命令种类，如果要看<br />种类中的命令，可以使用help 命令，如：help breakpoints，查看设置断点的所有命令。也<br />可以直接help 来查看命令的帮助。 <br />gdb中，输入命令时，可以不用打全命令，只用打命令的前几个字符就可以了，当然，命令<br />的前几个字符应该要标志着一个唯一的命令，在Linux下，你可以敲击两次TAB键来补齐<br />命令的全称，如果有重复的，那么gdb会把其例出来。 <br />示例一：在进入函数func时，设置一个断点。可以敲入break func，或是直接就是b func <br />(gdb) b func <br />Breakpoint 1 at 0x8048458: file hello.c, line 10. <br />示例二：敲入b按两次TAB键，你会看到所有b打头的命令： <br />(gdb) b <br />backtrace break bt <br />(gdb) <br />示例三：只记得函数的前缀，可以这样： <br />(gdb) b make_ &lt;按TAB键&gt; <br />（再按下一次TAB键，你会看到:） <br />make_a_section_from_file make_environ <br />make_abs_section make_function_type <br />make_blockvector make_pointer_type </p>
		<p>make_cleanup make_reference_type <br />make_command make_symbol_completion_list <br />(gdb) b make_ <br />GDB把所有make开头的函数全部例出来给你查看。 <br />示例四：调试C++的程序时，有可以函数名一样。如： <br />(gdb) b 'bubble( M-? <br />bubble(double,double) bubble(int,int) <br />(gdb) b 'bubble( <br />你可以查看到C++中的所有的重载函数及参数。（注：M-?和“按两次TAB键”是一个意思） <br />要退出gdb时，只用发quit或命令简称q就行了。 <br />GDB中运行UNIX的shell程序 <br />———————————— <br />在gdb环境中，你可以执行UNIX的shell的命令，使用gdb的shell命令来完成： <br />shell <br />调用UNIX的shell来执行，环境变量SHELL中定义的UNIX的shell将会被用来执行，如<br />果SHELL没有定义，那就使用UNIX的标准shell：/bin/sh。（在Windows中使用Command.com<br />或cmd.exe） <br />还有一个gdb命令是make： <br />make <br />可以在gdb中执行make命令来重新build自己的程序。这个命令等价于“shell make ”。 <br />在GDB中运行程序 <br />———————— <br />当以gdb 方式启动gdb后，gdb会在PATH路径和当前目录中搜索的源文件。如要确认gdb<br />是否读到源文件，可使用l或list命令，看看gdb是否能列出源代码。 <br />在gdb中，运行程序使用r或是run命令。程序的运行，你有可能需要设置下面四方面的事。 <br />1、程序运行参数。 <br />set args 可指定运行时参数。（如：set args 10 20 30 40 50） <br />show args 命令可以查看设置好的运行参数。 <br />2、运行环境。 <br />path <br />可设定程序的运行路径。 <br />show paths 查看程序的运行路径。 </p>
		<p>set environment varname [=value] 设置环境变量。如：set env USER=hchen <br />show environment [varname] 查看环境变量。 <br />3、工作目录。 <br />cd <br />相当于shell的cd命令。 <br />pwd 显示当前的所在目录。 <br />4、程序的输入输出。 <br />info terminal 显示你程序用到的终端的模式。 <br />使用重定向控制程序输出。如：run &gt; outfile <br />tty命令可以指写输入输出的终端设备。如：tty /dev/ttyb <br />调试已运行的程序 <br />———————— <br />两种方法： <br />1、在UNIX下用ps查看正在运行的程序的PID（进程ID），然后用gdb PID格式挂接正在<br />运行的程序。 <br />2、先用gdb 关联上源代码，并进行gdb，在gdb中用attach命令来挂接进程的PID。并用<br />detach来取消挂接的进程。 <br />暂停 / 恢复程序运行 <br />————————— <br />调试程序中，暂停程序运行是必须的，GDB可以方便地暂停程序的运行。你可以设置程序<br />的在哪行停住，在什么条件下停住，在收到什么信号时停往等等。以便于你查看运行时的变<br />量，以及运行时的流程。 <br />当进程被gdb停住时，你可以使用info program 来查看程序的是否在运行，进程号，被暂停<br />的原因。 <br />在gdb中，我们可以有以下几种暂停方式：断点（BreakPoint）、观察点（WatchPoint）、捕<br />捉点（CatchPoint）、信号（Signals）、线程停止（Thread Stops）。如果要恢复程序运行，可<br />以使用c或是continue命令。 <br />一、设置断点（BreakPoint） <br />我们用break命令来设置断点。正面有几点设置断点的方法： <br />break <br />在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函</p>
		<p>数名。 <br />break <br />在指定行号停住。 <br />break +offset <br />break -offset <br />在当前行号的前面或后面的offset行停住。offiset为自然数。 <br />break filename:linenum <br />在源文件filename的linenum行处停住。 <br />break filename:function <br />在源文件filename的function函数的入口处停住。 <br />break *address <br />在程序运行的内存地址处停住。 <br />break <br />break命令没有参数时，表示在下一条指令处停住。 <br />break ... if <br />...可以是上述的参数，condition表示条件，在条件成立时停住。比如在循环境体中，可以设<br />置break if i=100，表示当i为100时停住程序。 <br />查看断点时，可使用info命令，如下所示：（注：n表示断点号） <br />info breakpoints [n] <br />info break [n] <br />二、设置观察点（WatchPoint） <br />观察点一般来观察某个表达式（变量也是一种表达式）的值是否有变化了，如果有变化，马<br />上停住程序。我们有下面的几种方法来设置观察点： <br />watch <br />为表达式（变量）expr设置一个观察点。一量表达式值有变化时，马上停住程序。 <br />rwatch <br />当表达式（变量）expr被读时，停住程序。 <br />awatch <br />当表达式（变量）的值被读或被写时，停住程序。 </p>
		<p>info watchpoints <br />列出当前所设置了的所有观察点。 <br />三、设置捕捉点（CatchPoint） <br />你可设置捕捉点来补捉程序运行时的一些事件。如：载入共享库（动态链接库）或是C++<br />的异常。设置捕捉点的格式为： <br />catch <br />当event发生时，停住程序。event可以是下面的内容： <br />1、throw 一个C++抛出的异常。（throw为关键字） <br />2、catch 一个C++捕捉到的异常。（catch为关键字） <br />3、exec 调用系统调用exec时。（exec为关键字，目前此功能只在HP-UX下有用） <br />4、fork 调用系统调用fork时。（fork为关键字，目前此功能只在HP-UX下有用） <br />5、vfork 调用系统调用vfork时。（vfork为关键字，目前此功能只在HP-UX下有用） <br />6、load 或 load 载入共享库（动态链接库）时。（load为关键字，目前此功能只在HP-UX<br />下有用） <br />7、unload 或 unload 卸载共享库（动态链接库）时。（unload为关键字，目前此功能只在<br />HP-UX下有用） <br />tcatch <br />只设置一次捕捉点，当程序停住以后，应点被自动删除。 <br />四、维护停止点 <br />上面说了如何设置程序的停止点，GDB中的停止点也就是上述的三类。在GDB中，如果你<br />觉得已定义好的停止点没有用了，你可以使用delete、clear、disable、enable这几个命令来<br />进行维护。 <br />clear <br />清除所有的已定义的停止点。 <br />clear <br />clear <br />清除所有设置在函数上的停止点。 <br />clear <br />clear <br />清除所有设置在指定行上的停止点。 <br />delete [breakpoints] [range...] <br />删除指定的断点，breakpoints为断点号。如果不指定断点号，则表示删除所有的断点。range <br />表示断点号的范围（如：3-7）。其简写命令为d。 </p>
		<p>比删除更好的一种方法是disable停止点，disable了的停止点，GDB不会删除，当你还需要<br />时，enable即可，就好像回收站一样。 <br />disable [breakpoints] [range...] <br />disable所指定的停止点，breakpoints为停止点号。如果什么都不指定，表示disable所有的<br />停止点。简写命令是dis. <br />enable [breakpoints] [range...] <br />enable所指定的停止点，breakpoints为停止点号。 <br />enable [breakpoints] once range... <br />enable所指定的停止点一次，当程序停止后，该停止点马上被GDB自动disable。 <br />enable [breakpoints] delete range... <br />enable所指定的停止点一次，当程序停止后，该停止点马上被GDB自动删除。 <br />五、停止条件维护 <br />前面在说到设置断点时，我们提到过可以设置一个条件，当条件成立时，程序自动停止，这<br />是一个非常强大的功能，这里，我想专门说说这个条件的相关维护命令。一般来说，为断点<br />设置一个条件，我们使用if关键词，后面跟其断点条件。并且，条件设置好后，我们可以<br />用condition命令来修改断点的条件。（只有break和watch命令支持if，catch目前暂不支持<br />if） <br />condition <br />修改断点号为bnum的停止条件为expression。 <br />condition <br />清除断点号为bnum的停止条件。 <br />还有一个比较特殊的维护命令ignore，你可以指定程序运行时，忽略停止条件几次。 <br />ignore <br />表示忽略断点号为bnum的停止条件count次。 <br />六、为停止点设定运行命令 <br />我们可以使用GDB提供的command命令来设置停止点的运行命令。也就是说，当运行的<br />程序在被停止住时，我们可以让其自动运行一些别的命令，这很有利行自动化调试。对基于<br />GDB的自动化调试是一个强大的支持。 <br />commands [bnum] </p>
		<p>... command-list ... <br />end <br />为断点号bnum指写一个命令列表。当程序被该断点停住时，gdb会依次运行命令列表中的<br />命令。 <br />例如： <br />break foo if x&gt;0 <br />commands <br />printf "x is %d\n",x <br />continue <br />end <br />断点设置在函数foo中，断点条件是x&gt;0，如果程序被断住后，也就是，一旦x的值在foo<br />函数中大于0，GDB会自动打印出x的值，并继续运行程序。 <br />如果你要清除断点上的命令序列，那么只要简单的执行一下commands命令，并直接在打个<br />end就行了。 <br />七、断点菜单 <br />在C++中，可能会重复出现同一个名字的函数若干次（函数重载），在这种情况下，break 不<br />能告诉GDB要停在哪个函数的入口。当然，你可以使用break 也就是把函数的参数类型告<br />诉GDB，以指定一个函数。否则的话，GDB会给你列出一个断点菜单供你选择你所需要的<br />断点。你只要输入你菜单列表中的编号就可以了。如： <br />(gdb) b String::after <br />[0] cancel <br />[1] all <br />[2] file:String.cc; line number:867 <br />[3] file:String.cc; line number:860 <br />[4] file:String.cc; line number:875 <br />[5] file:String.cc; line number:853 <br />[6] file:String.cc; line number:846 <br />[7] file:String.cc; line number:735 <br />&gt; 2 4 6 <br />Breakpoint 1 at 0xb26c: file String.cc, line 867. <br />Breakpoint 2 at 0xb344: file String.cc, line 875. <br />Breakpoint 3 at 0xafcc: file String.cc, line 846. <br />Multiple breakpoints were set. <br />Use the "delete" command to delete unwanted <br />breakpoints. <br />(gdb) </p>
		<p>可见，GDB列出了所有after的重载函数，你可以选一下列表编号就行了。0表示放弃设置<br />断点，1表示所有函数都设置断点。 <br />八、恢复程序运行和单步调试 <br />当程序被停住了，你可以用continue命令恢复程序的运行直到程序结束，或下一个断点到来。<br />也可以使用step或next命令单步跟踪程序。 <br />continue [ignore-count] <br />c [ignore-count] <br />fg [ignore-count] <br />恢复程序运行，直到程序结束，或是下一个断点到来。ignore-count表示忽略其后的断点次<br />数。continue，c，fg三个命令都是一样的意思。 <br />step <br />单步跟踪，如果有函数调用，他会进入该函数。进入函数的前提是，此函数被编译有debug<br />信息。很像VC等工具中的step in。后面可以加count也可以不加，不加表示一条条地执行，<br />加表示执行后面的count条指令，然后再停住。 <br />next <br />同样单步跟踪，如果有函数调用，他不会进入该函数。很像VC等工具中的step over。后面<br />可以加count也可以不加，不加表示一条条地执行，加表示执行后面的count条指令，然后<br />再停住。 <br />set step-mode <br />set step-mode on <br />打开step-mode模式，于是，在进行单步跟踪时，程序不会因为没有debug信息而不停住。<br />这个参数有很利于查看机器码。 <br />set step-mod off <br />关闭step-mode模式。 <br />finish <br />运行程序，直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。 <br />until 或 u <br />当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 <br />stepi 或 si <br />nexti 或 ni <br />单步跟踪一条机器指令！一条程序代码有可能由数条机器指令完成，stepi和nexti可以单步<br />执行机器指令。与之一样有相同功能的命令是“display/i $pc” ，当运行完这个命令后，单<br />步跟踪会在打出程序代码的同时打出机器指令（也就是汇编代码） </p>
		<p>九、信号（Signals） <br />信号是一种软中断，是一种处理异步事件的方法。一般来说，操作系统都支持许多信号。尤<br />其是UNIX，比较重要应用程序一般都会处理信号。UNIX定义了许多信号，比如SIGINT<br />表示中断字符信号，也就是Ctrl+C的信号，SIGBUS表示硬件故障的信号；SIGCHLD表示<br />子进程状态改变信号；SIGKILL表示终止程序运行的信号，等等。信号量编程是UNIX下<br />非常重要的一种技术。 <br />GDB有能力在你调试程序的时候处理任何一种信号，你可以告诉GDB需要处理哪一种信<br />号。你可以要求GDB收到你所指定的信号时，马上停住正在运行的程序，以供你进行调试。<br />你可以用GDB的handle命令来完成这一功能。 <br />handle <br />在GDB中定义一个信号处理。信号可以以SIG开头或不以SIG开头，可以用定义一个要处<br />理信号的范围（如：SIGIO-SIGKILL，表示处理从SIGIO信号到SIGKILL的信号，其中包<br />括SIGIO，SIGIOT，SIGKILL三个信号），也可以使用关键字all来标明要处理所有的信号。<br />一旦被调试的程序接收到信号，运行程序马上会被GDB停住，以供调试。其可以是以下几<br />种关键字的一个或多个。 <br />nostop <br />当被调试的程序收到信号时，GDB不会停住程序的运行，但会打出消息告诉你收到这种信<br />号。 <br />stop <br />当被调试的程序收到信号时，GDB会停住你的程序。 <br />print <br />当被调试的程序收到信号时，GDB会显示出一条信息。 <br />noprint <br />当被调试的程序收到信号时，GDB不会告诉你收到信号的信息。 <br />pass <br />noignore <br />当被调试的程序收到信号时，GDB不处理信号。这表示，GDB会把这个信号交给被调试程<br />序会处理。 <br />nopass <br />ignore <br />当被调试的程序收到信号时，GDB不会让被调试程序来处理这个信号。 <br />info signals <br />info handle <br />查看有哪些信号在被GDB检测中。 <br />十、线程（Thread Stops） </p>
		<p>如果你程序是多线程的话，你可以定义你的断点是否在所有的线程上，或是在某个特定的线<br />程。GDB很容易帮你完成这一工作。 <br />break thread <br />break thread if ... <br />linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID，注意，这个ID是<br />GDB分配的，你可以通过“info threads”命令来查看正在运行程序中的线程信息。如果你<br />不指定thread 则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如： <br />(gdb) break frik.c:13 thread 28 if bartab &gt; lim <br />当你的程序被GDB停住时，所有的运行线程都会被停住。这方便你你查看运行程序的总体<br />情况。而在你恢复程序运行时，所有的线程也会被恢复运行。那怕是主进程在被单步调试时。 <br />查看栈信息 <br />————— <br />当程序被停住了，你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一<br />个函数，函数的地址，函数参数，函数内的局部变量都会被压入“栈”（Stack）中。你可以<br />用GDB命令来查看当前的栈中的信息。 <br />下面是一些查看函数调用栈信息的GDB命令： <br />backtrace <br />bt <br />打印当前的函数调用栈的所有信息。如： <br />(gdb) bt <br />#0 func (n=250) at tst.c:6 <br />#1 0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30 <br />#2 0x400409ed in __libc_start_main () from /lib/libc.so.6 <br />从上可以看出函数的调用栈信息：__libc_start_main --&gt; main() --&gt; func() <br />backtrace <br />bt <br />n是一个正整数，表示只打印栈顶上n层的栈信息。 <br />backtrace &lt;-n&gt; <br />bt &lt;-n&gt; <br />-n表一个负整数，表示只打印栈底下n层的栈信息。 <br />如果你要查看某一层的信息，你需要在切换当前的栈，一般来说，程序停止时，最顶层的栈</p>
		<p>就是当前栈，如果你要查看栈下面层的详细信息，首先要做的是切换当前栈。 <br />frame <br />f <br />n是一个从0开始的整数，是栈中的层编号。比如：frame 0，表示栈顶，frame 1，表示栈的<br />第二层。 <br />up <br />表示向栈的上面移动n层，可以不打n，表示向上移动一层。 <br />down <br />表示向栈的下面移动n层，可以不打n，表示向下移动一层。 <br />上面的命令，都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三<br />个命令： <br />select-frame 对应于 frame 命令。 <br />up-silently 对应于 up 命令。 <br />down-silently 对应于 down 命令。 <br />查看当前栈层的信息，你可以用以下GDB命令： <br />frame 或 f <br />会打印出这些信息：栈的层编号，当前的函数名，函数参数值，函数所在文件及行号，函数<br />执行到的语句。 <br />info frame <br />info f <br />这个命令会打印出更为详细的当前栈层的信息，只不过，大多数都是运行时的内内地址。比<br />如：函数地址，调用函数的地址，被调用函数的地址，目前的函数是由什么样的程序语言写<br />成的、函数参数地址及值、局部变量的地址等等。如： <br />(gdb) info f <br />Stack level 0, frame at 0xbffff5d4: <br />eip = 0x804845d in func (tst.c:6); saved eip 0x8048524 <br />called by frame at 0xbffff60c <br />source language c. <br />Arglist at 0xbffff5d4, args: n=250 <br />Locals at 0xbffff5d4, Previous frame's sp is 0x0 <br />Saved registers: <br />ebp at 0xbffff5d4, eip at 0xbffff5d8 <br />info args </p>
		<p>打印出当前函数的参数名及其值。 <br />info locals <br />打印出当前函数中所有局部变量及其值。 <br />info catch <br />打印出当前的函数中的异常处理信息。 <br />查看源程序 <br />————— <br />一、显示源代码 <br />GDB 可以打印出所调试程序的源代码，当然，在程序编译时一定要加上-g的参数，把源程<br />序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后，GDB会报告程序<br />停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。还是来看一看查看源<br />代码的GDB命令吧。 <br />list <br />显示程序第linenum行的周围的源程序。 <br />list <br />显示函数名为function的函数的源程序。 <br />list <br />显示当前行后面的源程序。 <br />list - <br />显示当前行前面的源程序。 <br />一般是打印当前行的上5行和下5行，如果显示函数是是上2行下8行，默认是10行，当<br />然，你也可以定制显示的范围，使用下面命令可以设置一次显示源程序的行数。 <br />set listsize <br />设置一次显示源代码的行数。 <br />show listsize <br />查看当前listsize的设置。 <br />list命令还有下面的用法： <br />list , </p>
		<p>显示从first行到last行之间的源代码。 <br />list , <br />显示从当前行到last行之间的源代码。 <br />list + <br />往后显示源代码。 <br />一般来说在list后面可以跟以下这们的参数： <br />行号。 <br />&lt;+offset&gt; 当前行号的正偏移量。 <br />&lt;-offset&gt; 当前行号的负偏移量。 <br />哪个文件的哪一行。 <br />函数名。 <br />哪个文件中的哪个函数。 <br />&lt;*address&gt; 程序运行时的语句在内存中的地址。 <br />二、搜索源代码 <br />不仅如此，GDB还提供了源代码搜索的命令： <br />forward-search <br />search <br />向前面搜索。 <br />reverse-search <br />全部搜索。 <br />其中，就是正则表达式，也主一个字符串的匹配模式，关于正则表达式，我就不在这里讲了，<br />还请各位查看相关资料。 <br />三、指定源文件的路径 <br />某些时候，用-g编译过后的执行程序中只是包括了源文件的名字，没有路径名。GDB提供<br />了可以让你指定源文件的路径的命令，以便GDB进行搜索。 <br />directory <br />dir <br />加一个源文件路径到当前路径的前面。如果你要指定多个路径，UNIX下你可以使用“:”，<br />Windows下你可以使用“;”。 </p>
		<p>directory <br />清除所有的自定义的源文件搜索路径信息。 <br />show directories <br />显示定义了的源文件搜索路径。 <br />四、源代码的内存 <br />你可以使用info line命令来查看源代码在内存中的地址。info line后面可以跟“行号”，“函<br />数名”，“文件名:行号”，“文件名:函数名”，这个命令会打印出所指定的源码在运行时的内<br />存地址，如： <br />(gdb) info line tst.c:func <br />Line 5 of "tst.c" starts at address 0x8048456 and ends at 0x804845d . <br />还有一个命令（disassemble）你可以查看源程序的当前执行时的机器码，这个命令会把目前<br />内存中的指令dump出来。如下面的示例表示查看函数func的汇编代码。 <br />(gdb) disassemble func <br />Dump of assembler code for function func: <br />0x8048450 : push %ebp <br />0x8048451 : mov %esp,%ebp <br />0x8048453 : sub $0x18,%esp <br />0x8048456 : movl $0x0,0xfffffffc(%ebp) <br />0x804845d : movl $0x1,0xfffffff8(%ebp) <br />0x8048464 : mov 0xfffffff8(%ebp),%eax <br />0x8048467 : cmp 0x8(%ebp),%eax <br />0x804846a : jle 0x8048470 <br />0x804846c : jmp 0x8048480 <br />0x804846e : mov %esi,%esi <br />0x8048470 : mov 0xfffffff8(%ebp),%eax <br />0x8048473 : add %eax,0xfffffffc(%ebp) <br />0x8048476 : incl 0xfffffff8(%ebp) <br />0x8048479 : jmp 0x8048464 <br />0x804847b : nop <br />0x804847c : lea 0x0(%esi,1),%esi <br />0x8048480 : mov 0xfffffffc(%ebp),%edx <br />0x8048483 : mov %edx,%eax <br />0x8048485 : jmp 0x8048487 <br />0x8048487 : mov %ebp,%esp <br />0x8048489 : pop %ebp <br />0x804848a : ret <br />End of assembler dump. </p>
		<p>查看运行时数据 <br />——————— <br />在你调试程序时，当程序被停住时，你可以使用print命令（简写命令为p），或是同义命令<br />inspect来查看当前程序的运行数据。print命令的格式是： <br />print <br />print / <br />是表达式，是你所调试的程序的语言的表达式（GDB可以调试多种编程语言），是输出的格<br />式，比如，如果要把表达式按16进制的格式输出，那么就是/x。 <br />一、表达式 <br />print和许多GDB的命令一样，可以接受一个表达式，GDB会根据当前的程序运行的数据<br />来计算这个表达式，既然是表达式，那么就可以是当前程序运行中的const常量、变量、函<br />数等内容。可惜的是GDB不能使用你在程序中所定义的宏。 <br />表达式的语法应该是当前所调试的语言的语法，由于C/C++是一种大众型的语言，所以，本<br />文中的例子都是关于C/C++的。（而关于用GDB调试其它语言的章节，我将在后面介绍） <br />在表达式中，有几种GDB所支持的操作符，它们可以用在任何一种语言中。 <br />@ <br />是一个和数组有关的操作符，在后面会有更详细的说明。 <br />:: <br />指定一个在文件或是一个函数中的变量。 <br />{} <br />表示一个指向内存地址的类型为type的一个对象。 <br />二、程序变量 <br />在GDB中，你可以随时查看以下三种变量的值： <br />1、全局变量（所有文件可见的） <br />2、静态全局变量（当前文件可见的） <br />3、局部变量（当前Scope可见的） <br />如果你的局部变量和全局变量发生冲突（也就是重名），一般情况下是局部变量会隐藏全局<br />变量，也就是说，如果一个全局变量和一个函数中的局部变量同名时，如果当前停止点在函</p>
		<p>数中，用print显示出的变量的值会是函数中的局部变量的值。如果此时你想查看全局变量<br />的值时，你可以使用“::”操作符： <br />file::variable <br />function::variable <br />可以通过这种形式指定你所想查看的变量，是哪个文件中的或是哪个函数中的。例如，查看<br />文件f2.c中的全局变量x的值： <br />gdb) p 'f2.c'::x <br />当然，“::”操作符会和C++中的发生冲突，GDB能自动识别“::” 是否C++的操作符，所<br />以你不必担心在调试C++程序时会出现异常。 <br />另外，需要注意的是，如果你的程序编译时开启了优化选项，那么在用GDB调试被优化过<br />的程序时，可能会发生某些变量不能访问，或是取值错误码的情况。这个是很正常的，因为<br />优化程序会删改你的程序，整理你程序的语句顺序，剔除一些无意义的变量等，所以在GDB<br />调试这种程序时，运行时的指令和你所编写指令就有不一样，也就会出现你所想象不到的结<br />果。对付这种情况时，需要在编译程序时关闭编译优化。一般来说，几乎所有的编译器都支<br />持编译优化的开关，例如，GNU的C/C++编译器GCC，你可以使用“-gstabs”选项来解决<br />这个问题。关于编译器的参数，还请查看编译器的使用说明文档。 <br />三、数组 <br />有时候，你需要查看一段连续的内存空间的值。比如数组的一段，或是动态分配的数据的大<br />小。你可以使用GDB的“@”操作符，“@”的左边是第一个内存的地址的值，“@”的右<br />边则你你想查看内存的长度。例如，你的程序中有这样的语句： <br />int *array = (int *) malloc (len * sizeof (int)); <br />于是，在GDB调试过程中，你可以以如下命令显示出这个动态数组的取值： <br />p <a href="mailto:*array@len"><strong><font color="#006bad">*array@len</font></strong></a><br />@的左边是数组的首地址的值，也就是变量array所指向的内容，右边则是数据的长度，其<br />保存在变量len中，其输出结果，大约是下面这个样子的： <br />(gdb) p <a href="mailto:*array@len"><strong><font color="#006bad">*array@len</font></strong></a><br />$1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40} <br />如果是静态数组的话，可以直接用print数组名，就可以显示数组中所有数据的内容了。 <br />四、输出格式 </p>
		<p>一般来说，GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。<br />例如，你想输出一个整数的十六进制，或是二进制来查看这个整型变量的中的位的情况。要<br />做到这样，你可以使用GDB的数据显示格式： <br />x 按十六进制格式显示变量。 <br />d 按十进制格式显示变量。 <br />u 按十六进制格式显示无符号整型。 <br />o 按八进制格式显示变量。 <br />t 按二进制格式显示变量。 <br />a 按十六进制格式显示变量。 <br />c 按字符格式显示变量。 <br />f 按浮点数格式显示变量。 <br />(gdb) p i <br />$21 = 101 <br />(gdb) p/a i <br />$22 = 0x65 <br />(gdb) p/c i <br />$23 = 101 'e' <br />(gdb) p/f i <br />$24 = 1.41531145e-43 <br />(gdb) p/x i <br />$25 = 0x65 <br />(gdb) p/t i <br />$26 = 1100101 <br />五、查看内存 <br />你可以使用examine命令（简写是x）来查看内存地址中的值。x命令的语法如下所示： <br />x/ <br />n、f、u是可选的参数。 <br />n 是一个正整数，表示显示内存的长度，也就是说从当前地址向后显示几个地址的内容。 <br />f 表示显示的格式，参见上面。如果地址所指的是字符串，那么格式可以是s，如果地十是<br />指令地址，那么格式可以是i。 </p>
		<p>u 表示从当前地址往后请求的字节数，如果不指定的话，GDB默认是4个bytes。u参数可<br />以用下面的字符来代替，b表示单字节，h表示双字节，w表示四字节，g表示八字节。当<br />我们指定了字节长度后，GDB会从指内存定的内存地址开始，读写指定字节，并把其当作<br />一个值取出来。 <br />表示一个内存地址。 <br />n/f/u三个参数可以一起使用。例如： <br />命令：x/3uh 0x54320 表示，从内存地址0x54320读取内容，h表示以双字节为一个单位，3<br />表示三个单位，u表示按十六进制显示。 <br />六、自动显示 <br />你可以设置一些自动显示的变量，当程序停住时，或是在你单步跟踪时，这些变量会自动显<br />示。相关的GDB命令是display。 <br />display <br />display/ <br />display/ <br />expr是一个表达式，fmt表示显示的格式，addr表示内存地址，当你用display设定好了一<br />个或多个表达式后，只要你的程序被停下来，GDB会自动显示你所设置的这些表达式的值。 <br />格式i和s同样被display支持，一个非常有用的命令是： <br />display/i $pc <br />$pc是GDB的环境变量，表示着指令的地址，/i则表示输出格式为机器指令码，也就是汇<br />编。于是当程序停下后，就会出现源代码和机器指令码相对应的情形，这是一个很有意思的<br />功能。 <br />下面是一些和display相关的GDB命令： <br />undisplay <br />delete display <br />删除自动显示，dnums意为所设置好了的自动显式的编号。如果要同时删除几个，编号可以<br />用空格分隔，如果要删除一个范围内的编号，可以用减号表示（如：2-5） <br />disable display <br />enable display <br />disable和enalbe不删除自动显示的设置，而只是让其失效和恢复。 </p>
		<p>info display <br />查看display设置的自动显示的信息。GDB会打出一张表格，向你报告当然调试中设置了多<br />少个自动显示设置，其中包括，设置的编号，表达式，是否enable。 <br />七、设置显示选项 <br />GDB中关于显示的选项比较多，这里我只例举大多数常用的选项。 <br />set print address <br />set print address on <br />打开地址输出，当程序显示函数信息时，GDB会显出函数的参数地址。系统默认为打开的，<br />如： <br />(gdb) f <br />#0 set_quotes (lq=0x34c78 "&lt;&lt;", rq=0x34c88 "&gt;&gt;") <br />at input.c:530 <br />530 if (lquote != def_lquote) <br />set print address off <br />关闭函数的参数地址显示，如： <br />(gdb) set print addr off <br />(gdb) f <br />#0 set_quotes (lq="&lt;&lt;", rq="&gt;&gt;") at input.c:530 <br />530 if (lquote != def_lquote) <br />show print address <br />查看当前地址显示选项是否打开。 <br />set print array <br />set print array on <br />打开数组显示，打开后当数组显示时，每个元素占一行，如果不打开的话，每个元素则以逗<br />号分隔。这个选项默认是关闭的。与之相关的两个命令如下，我就不再多说了。 <br />set print array off <br />show print array <br />set print elements <br />这个选项主要是设置数组的，如果你的数组太大了，那么就可以指定一个来指定数据显示的<br />最大长度，当到达这个长度时，GDB就不再往下显示了。如果设置为0，则表示不限制。 <br />show print elements </p>
		<p>查看print elements的选项信息。 <br />set print null-stop <br />如果打开了这个选项，那么当显示字符串时，遇到结束符则停止显示。这个选项默认为off。 <br />set print pretty on <br />如果打开printf pretty这个选项，那么当GDB显示结构体时会比较漂亮。如： <br />$1 = { <br />next = 0x0, <br />flags = { <br />sweet = 1, <br />sour = 1 <br />}, <br />meat = 0x54 "Pork" <br />} <br />set print pretty off <br />关闭printf pretty这个选项，GDB显示结构体时会如下显示： <br />$1 = {next = 0x0, flags = {sweet = 1, sour = 1}, meat = 0x54 "Pork"} <br />show print pretty <br />查看GDB是如何显示结构体的。 <br />set print sevenbit-strings <br />设置字符显示，是否按“\nnn”的格式显示，如果打开，则字符串或字符数据按\nnn显示，<br />如“\065”。 <br />show print sevenbit-strings <br />查看字符显示开关是否打开。 <br />set print union <br />设置显示结构体时，是否显式其内的联合体数据。例如有以下数据结构： <br />typedef enum {Tree, Bug} Species; <br />typedef enum {Big_tree, Acorn, Seedling} Tree_forms; <br />typedef enum {Caterpillar, Cocoon, Butterfly} <br />Bug_forms; <br />struct thing { <br />Species it; <br />union { </p>
		<p>Tree_forms tree; <br />Bug_forms bug; <br />} form; <br />}; <br />struct thing foo = {Tree, {Acorn}}; <br />当打开这个开关时，执行 p foo 命令后，会如下显示： <br />$1 = {it = Tree, form = {tree = Acorn, bug = Cocoon}} <br />当关闭这个开关时，执行 p foo 命令后，会如下显示： <br />$1 = {it = Tree, form = {...}} <br />show print union <br />查看联合体数据的显示方式 <br />set print object <br />在C++中，如果一个对象指针指向其派生类，如果打开这个选项，GDB会自动按照虚方法<br />调用的规则显示输出，如果关闭这个选项的话，GDB就不管虚函数表了。这个选项默认是<br />off。 <br />show print object <br />查看对象选项的设置。 <br />set print static-members <br />这个选项表示，当显示一个C++对象中的内容是，是否显示其中的静态数据成员。默认是<br />on。 <br />show print static-members <br />查看静态数据成员选项设置。 <br />set print vtbl <br />当此选项打开时，GDB将用比较规整的格式来显示虚函数表时。其默认是关闭的。 <br />show print vtbl <br />查看虚函数显示格式的选项。 <br />八、历史记录 <br />当你用GDB的print查看程序运行时的数据时，你每一个print都会被GDB记录下来。GDB<br />会以$1, $2, $3 .....这样的方式为你每一个print命令编上号。于是，你可以使用这个编号访问<br />以前的表达式，如$1。这个功能所带来的好处是，如果你先前输入了一个比较长的表达式，<br />如果你还想查看这个表达式的值，你可以使用历史记录来访问，省去了重复输入。 </p>
		<p>九、GDB环境变量 <br />你可以在GDB的调试环境中定义自己的变量，用来保存一些调试程序中的运行数据。要定<br />义一个GDB的变量很简单只需。使用GDB的set命令。GDB的环境变量和UNIX一样，<br />也是以$起头。如： <br />set $foo = *object_ptr <br />使用环境变量时，GDB会在你第一次使用时创建这个变量，而在以后的使用中，则直接对<br />其賦值。环境变量没有类型，你可以给环境变量定义任一的类型。包括结构体和数组。 <br />show convenience <br />该命令查看当前所设置的所有的环境变量。 <br />这是一个比较强大的功能，环境变量和程序变量的交互使用，将使得程序调试更为灵活便捷。<br />例如： <br />set $i = 0 <br />print bar[$i++]-&gt;contents <br />于是，当你就不必，print bar[0]-&gt;contents, print bar[1]-&gt;contents地输入命令了。输入这样的<br />命令后，只用敲回车，重复执行上一条语句，环境变量会自动累加，从而完成逐个输出的功<br />能。 <br />十、查看寄存器 <br />要查看寄存器的值，很简单，可以使用如下命令： <br />info registers <br />查看寄存器的情况。（除了浮点寄存器） <br />info all-registers <br />查看所有寄存器的情况。（包括浮点寄存器） <br />info registers <br />查看所指定的寄存器的情况。 <br />寄存器中放置了程序运行时的数据，比如程序当前运行的指令地址（ip），程序的当前堆栈<br />地址（sp）等等。你同样可以使用print命令来访问寄存器的情况，只需要在寄存器名字前<br />加一个$符号就可以了。如：p $eip。 </p>
		<p>改变程序的执行 <br />——————— <br />一旦使用GDB挂上被调试程序，当程序运行起来后，你可以根据自己的调试思路来动态地<br />在GDB中更改当前被调试程序的运行线路或是其变量的值，这个强大的功能能够让你更好<br />的调试你的程序，比如，你可以在程序的一次运行中走遍程序的所有分支。 <br />一、修改变量值 <br />修改被调试程序运行时的变量值，在GDB中很容易实现，使用GDB的print命令即可完成。<br />如： <br />(gdb) print x=4 <br />x=4这个表达式是C/C++的语法，意为把变量x的值修改为4，如果你当前调试的语言是<br />Pascal，那么你可以使用Pascal的语法：x:=4。 <br />在某些时候，很有可能你的变量和GDB中的参数冲突，如： <br />(gdb) whatis width <br />type = double <br />(gdb) p width <br />$4 = 13 <br />(gdb) set width=47 <br />Invalid syntax in expression. <br />因为，set width是GDB的命令，所以，出现了“Invalid syntax in expression”的设置错误，<br />此时，你可以使用set var命令来告诉GDB，width不是你GDB的参数，而是程序的变量名，<br />如： <br />(gdb) set var width=47 <br />另外，还可能有些情况，GDB并不报告这种错误，所以保险起见，在你改变程序变量取值<br />时，最好都使用set var格式的GDB命令。 <br />二、跳转执行 <br />一般来说，被调试程序会按照程序代码的运行顺序依次执行。GDB提供了乱序执行的功能，<br />也就是说，GDB可以修改程序的执行顺序，可以让程序执行随意跳跃。这个功能可以由GDB<br />的jump命令来完： <br />jump </p>
		<p>指定下一条语句的运行点。可以是文件的行号，可以是file:line格式，可以是+num这种偏<br />移量格式。表式着下一条运行语句从哪里开始。 <br />jump <br />这里的 <br />是代码行的内存地址。 <br />注意，jump命令不会改变当前的程序栈中的内容，所以，当你从一个函数跳到另一个函数<br />时，当函数运行完返回时进行弹栈操作时必然会发生错误，可能结果还是非常奇怪的，甚至<br />于产生程序Core Dump。所以最好是同一个函数中进行跳转。 <br />熟悉汇编的人都知道，程序运行时，有一个寄存器用于保存当前代码所在的内存地址。所以，<br />jump命令也就是改变了这个寄存器中的值。于是，你可以使用“set $pc”来更改跳转执行<br />的地址。如： <br />set $pc = 0x485 <br />三、产生信号量 <br />使用singal命令，可以产生一个信号量给被调试的程序。如：中断信号Ctrl+C。这非常方便<br />于程序的调试，可以在程序运行的任意位置设置断点，并在该断点用GDB产生一个信号量，<br />这种精确地在某处产生信号非常有利程序的调试。 <br />语法是：signal ，UNIX的系统信号量通常从1到15。所以取值也在这个范围。 <br />single命令和shell的kill命令不同，系统的kill命令发信号给被调试程序时，是由GDB截<br />获的，而single命令所发出一信号则是直接发给被调试程序的。 <br />四、强制函数返回 <br />如果你的调试断点在某个函数中，并还有语句没有执行完。你可以使用return命令强制函数<br />忽略还没有执行的语句并返回。 <br />return <br />return <br />使用return命令取消当前函数的执行，并立即返回，如果指定了，那么该表达式的值会被认<br />作函数的返回值。 <br />五、强制调用函数 </p>
		<p>call <br />表达式中可以一是函数，以此达到强制调用函数的目的。并显示函数的返回值，如果函数返<br />回值是void，那么就不显示。 <br />另一个相似的命令也可以完成这一功能——print，print后面可以跟表达式，所以也可以用他<br />来调用函数，print和call的不同是，如果函数返回void，call则不显示，print则显示函数返<br />回值，并把该值存入历史数据中。 <br />在不同语言中使用GDB <br />—————————— <br />GDB支持下列语言：C, C++, Fortran, PASCAL, Java, Chill, assembly, 和 Modula-2。一般说<br />来，GDB会根据你所调试的程序来确定当然的调试语言，比如：发现文件名后缀为“.c”<br />的，GDB会认为是C程序。文件名后缀为“.C, .cc, .cp, .cpp, .cxx, .c++”的，GDB会认为是<br />C++程序。而后缀是“.f, .F”的，GDB会认为是Fortran程序，还有，后缀为如果是“.s, .S”<br />的会认为是汇编语言。 <br />也就是说，GDB会根据你所调试的程序的语言，来设置自己的语言环境，并让GDB的命令<br />跟着语言环境的改变而改变。比如一些GDB命令需要用到表达式或变量时，这些表达式或<br />变量的语法，完全是根据当前的语言环境而改变的。例如C/C++中对指针的语法是*p，而在<br />Modula-2中则是p^。并且，如果你当前的程序是由几种不同语言一同编译成的，那到在调<br />试过程中，GDB也能根据不同的语言自动地切换语言环境。这种跟着语言环境而改变的功<br />能，真是体贴开发人员的一种设计。 <br />下面是几个相关于GDB语言环境的命令： <br />show language <br />查看当前的语言环境。如果GDB不能识为你所调试的编程语言，那么，C语言被认为是默<br />认的环境。 <br />info frame <br />查看当前函数的程序语言。 <br />info source <br />查看当前文件的程序语言。 <br />如果GDB没有检测出当前的程序语言，那么你也可以手动设置当前的程序语言。使用set <br />language命令即可做到。 <br />当set language命令后什么也不跟的话，你可以查看GDB所支持的语言种类： </p>
		<p>(gdb) set language <br />The currently understood settings are: <br />local or auto Automatic setting based on source file <br />c Use the C language <br />c++ Use the C++ language <br />asm Use the Asm language <br />chill Use the Chill language <br />fortran Use the Fortran language <br />java Use the Java language <br />modula-2 Use the Modula-2 language <br />pascal Use the Pascal language <br />scheme Use the Scheme language <br />于是你可以在set language后跟上被列出来的程序语言名，来设置当前的语言环境。 <br />后记 <br />—— <br />GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于，其可以形成执行序<br />列，形成脚本。UNIX下的软件全是命令行的，这给程序开发提代供了极大的便利，命令行<br />软件的优势在于，它们可以非常容易的集成在一起，使用几个简单的已有工具的命令，就可<br />以做出一个非常强大的功能。 <br />于是UNIX下的软件比Windows下的软件更能有机地结合，各自发挥各自的长处，组合成<br />更为强劲的功能。而Windows下的图形软件基本上是各自为营，互相不能调用，很不利于<br />各种软件的相互集成。在这里并不是要和Windows做个什么比较，所谓“寸有所长，尺有<br />所短”，图形化工具还是有不如命令行的地方。（看到这句话时，希望各位千万再也不要认为<br />我就是“鄙视图形界面”，和我抬杠了 ） <br />我是根据版本为5.1.1的GDB所写的这篇文章，所以可能有些功能已被修改，或是又有更<br />为强劲的功能。而且，我写得非常仓促，写得比较简略，并且，其中我已经看到有许多错别<br />字了（我用五笔，所以错字让你看不懂），所以，我在这里对我文中的差错表示万分的歉意。 <br />文中所罗列的GDB的功能时，我只是罗列了一些带用的GDB的命令和使用方法，其实，<br />我这里只讲述的功能大约只占GDB所有功能的60%吧，详细的文档，还是请查看GDB的<br />帮助和使用手册吧，或许，过段时间，如果我有空，我再写一篇GDB的高级使用。 <br />我个人非常喜欢GDB的自动调试的功能，这个功能真的很强大，试想，我在UNIX下写个<br />脚本，让脚本自动编译我的程序，被自动调试，并把结果报告出来，调试成功，自动checkin<br />源码库。一个命令，编译带着调试带着checkin，多爽啊。只是GDB对自动化调试目前支持<br />还不是很成熟，只能实现半自动化，真心期望着GDB的自动化调试功能的成熟。 </p>
		<p>如果各位对GDB或是别的技术问题有兴趣的话，欢迎和我讨论交流。本人目前主要在UNIX<br />下做产品软件的开发，所以，对UNIX下的软件开发比较熟悉，当然，不单单是技术，对软<br />件工程实施，软件设计，系统分析，项目管理我也略有心得。欢迎大家找我交流，（QQ是：<br />753640，MSN是：<a href="mailto:haoel@hotmail.com"><strong><font color="#006bad">haoel@hotmail.com</font></strong></a>） <br />RelatedEntries： <br />文件操作 - 10 28, 2003 <br />OSW:12.CVS设置与应用 - 10 28, 2003 <br />MySQL AB Acquires Alzato - 10 24, 2003 <br />cvs - 10 24, 2003 <br />使用CVS进行版本管理 - 10 23, 2003 </p>
		<p> </p>
		<br />
		<br />
		<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=967657</p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/38245.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2007-12-29 15:42 <a href="http://www.cnitblog.com/guopingleee/archive/2007/12/29/38245.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字节顺序的详细解释</title><link>http://www.cnitblog.com/guopingleee/archive/2007/12/29/38244.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 29 Dec 2007 07:39:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2007/12/29/38244.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/38244.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2007/12/29/38244.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/38244.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/38244.html</trackback:ping><description><![CDATA[
		<p>这个人说得很好, 看到真让我懂了!!,  每个人都能懂! <br /><br />字节顺序的详细解释</p>
		<p>草木瓜 2006.7.26</p>
		<p>一、基本概念</p>
		<p>位的概念：在计算机中，一个0或1称为一位(bit)。</p>
		<p>字节：连续的八位称为一个字节(Byte)，字节是计算机中可单独处理的最小单位。即以字节<br />为基本单位来解释信息，规定1个字节是8个二进制位。</p>
		<p>通常1个ASCII码用1个字节存放，1个汉字用2个字节存放，双精度浮点实数用8个字节存放。<br />下面列表C语言中定义类型所占字节以及数据范围。</p>
		<p>
				<br />类型标识符         类型说明    长度(字节)  范围                       备注 </p>
		<p>char               字符型           1      -128 ~ 127                -2^7~(2^7-1) <br />unsigned char      无符字符型       1      0 ~ 255                    0~(2^8-1) <br />short int          短整型           2      -32768 ~ 32767           -2^15~(2^15-1) <br />unsigned short int 无符短整型       2      0 ~ 65535                  0~(2^16-1) <br />int                整型             4      -2147483648 ~ 2147483647 -2^31~(2^31-1) <br />unsigned int       无符整型         4      0 ~ 4294967295             0~(2^32-1) <br />float              实型（单精度）   4      1.18*10-38 ~ 3.40*1038     7位有效位 <br />double             实型（双精度）   8      2.23*10-308 ~ 1.79*10308   15位有效位 <br />long double        实型（长双精度） 10     3.37*10-4932 ~ 1.18*104932 19位有效位 </p>
		<p>
				<br />二、字节顺序由来</p>
		<p>我们在写字符流时，因为字符型只占一个字节数，计算机只须按一个字符一个字符<br />写入文件即可。但是如果是处理整型时，由于整型占4个字节，所以一个整型内部的<br />字节存储排列的顺序直接关系到被计算机识别出来的整型值。某种意义上也可直接<br />理解计算机的识别顺序就是所谓的字节顺序。</p>
		<p>
				<br />三、一些有关字节顺序的解释</p>
		<p>不同的计算机结构有时使用不同的字节顺序存储数据。例如，基于Intel的计算机存储数据<br />的顺序与Macintosh(Motorola)计算机就是相反的。Intel字节顺序称为“Little-Endian”，<br />反之Macintosh(Motorola)，还有网络上采用标准是“Big-Endian”。在将应用程序从一种架<br />构类型迁移至另一种架构类型的过程中，经常会遇到字节排列顺序（endianness）问题。<br />字节排列顺序是数据元素及其单个字节在内存中存储和表示时的顺序。</p>
		<p>通过以上分析，会发现有两类字节排列顺序：big-endian (通常为网络字节顺序)和<br />little-endian(主机字节顺序)。</p>
		<p>下面是这些术语的废话解释。 </p>
		<p>Big-Endian        最重要的字节在整个内容的左端。  <br />Little-Endian     最重要的字节在整个内容的右端。  <br />对于big-endian处理器，在将字放在内存中时，是从最低位地址开始的，首先放入最重要的<br />字节。另一方面，对于little-endian处理器，如Intel处理器，首先放入的是最不重要的字<br />节。</p>
		<p>说完上面的概念还是很模糊，个人认为对于不了解的字节顺序的人绝对是废话，网上大多都<br />是照搬照抄这几段废话。具体我们通过实际例子说明。</p>
		<p>
				<br />四、这里的解释说明</p>
		<p>  我们先看下面的代码，看完啥都明白了。<br />  <br />  这是运行在HP-UNIX 9000/800下完整的C语言代码，即为 Big-Endian 方式。<br />  <br />  #include &lt;unistd.h&gt;<br />  void main()<br />  {<br />  <br />  int i=0x41424344;<br />  <br />  printf("int  Address:%x Value:%x\n",&amp;i,i);<br />  printf("-------------------------------\n");<br />  <br />  char* pAddress=(char*)&amp;i;<br />  int j;<br />  <br />  for(j=0;j&lt;=3;j++)<br />  {<br />   printf("char Address:%x Value:%c\n",pAddress,*pAddress);<br />   pAddress++;<br />  }<br />  <br />  }<br />  <br />  编译输出(cc -g ...)：<br />  <br />  int  Address:7f7f08f0 Value:41424344<br />  -------------------------------<br />  char Address:7f7f08f0 Value:A<br />  char Address:7f7f08f1 Value:B<br />  char Address:7f7f08f2 Value:C<br />  char Address:7f7f08f3 Value:D</p>
		<p>    我们回到Windows XP下，看看这段代码的输出。Little-Endian 模式。<br />    <br />  #include &lt;stdio.h&gt;<br />  void main()<br />  {<br />   int i=0x41424344;<br />   printf("int  Address:%x Value:%x\n",&amp;i,i);<br />   printf("-------------------------------\n");<br />   char* pAddress=(char*)&amp;i;<br />   int j;<br />   for(j=0;j&lt;=3;j++)<br />   {<br />    printf("char Address:%x Value:%c\n",pAddress,*pAddress);<br />    pAddress++;<br />   }<br />  }</p>
		<p>  编译输出(VC 6.0)：<br />  <br />  int  Address:12ff7c Value:41424344<br />  -------------------------------<br />  char Address:12ff7c Value:D<br />  char Address:12ff7d Value:C<br />  char Address:12ff7e Value:B<br />  char Address:12ff7f Value:A<br />   <br />  </p>
		<p>    看完上面代码，应该就很清楚了，什么字节顺序？真是简单的要死！int i=0x41424344;<br />    采用16进制，我们知道A的ACSII码是65，16进制就是41，可以理解，本例是想通过输出<br />    A,B,C,D来验证字节顺序。我再对内存数据进行列表，相信会更有深层次的理解。<br />    </p>
		<p>  Big-Endian的内存放置顺序如下：<br />  <br />  地址：0x7f7f08f0  0x7f7f08f1  0x7f7f08f2  0x7f7f08f3<br />  <br />        0x41        0x42        0x43        0x44<br />      <br />  Little-Endian的内存放置顺序如下：</p>
		<p>  地址：0x0012ff7c  0x0012ff7d  0x0012ff7e  0x0012ff7f<br />  <br />        0x44        0x43        0x42        0x41</p>
		<p>五、最后的说明</p>
		<p>  主机字节顺序(Host)<br />  Little-Endian [ Intel、VAX和Unisys处理器 等]<br />  网络字节顺序(Network)<br />  Big-Endian [ IBM 370、Motorola和大多数RISC设计 ---- IBM 大型机和大多数Unix平台 ]</p>
		<p>  字节转换多半应用在网络编程，或者代码移植的情况下。<br />  Unix环境下的一些相关函数：（必须包含头文件 #include &lt;netinet/in.h&gt;)<br />  <br />  htons()--"Host to Network Short"<br />  htonl()--"Host to Network Long"<br />  ntohs()--"Network to Host Short"<br />  ntohl()--"Network to Host Long"<br />  <br />  Windows .Net 一些相关函数:<br />  <br />  HostToNetworkOrder<br />  NetworkToHostOrder<br />  </p>
		<br />
		<br />
		<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=980278</p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/38244.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2007-12-29 15:39 <a href="http://www.cnitblog.com/guopingleee/archive/2007/12/29/38244.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>( 精 )Linux下线程的创建 </title><link>http://www.cnitblog.com/guopingleee/archive/2007/12/27/38162.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Thu, 27 Dec 2007 06:13:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2007/12/27/38162.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/38162.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2007/12/27/38162.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/38162.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/38162.html</trackback:ping><description><![CDATA[
		<dl>
				<dd>这几个月还真够忙了,   忙.......也没时间来这里,   但看到好的资料还是想写在这里, 能给自己加深记忆, 忘记了还可来这里看看,  这都非常适合新手,  对新手非常有用!<br /><br /><br />作者:Hoyt Email:hoytluo@21cn.com </dd>
		</dl>
		<p>前言: Linux下线程的创建和基本的使用 </p>
		<ul>
				<li>线程的同步和互斥 
</li>
				<li>线程的条件变量 </li>
		</ul>
		<p>先介绍<strong><font style="BACKGROUND-COLOR: #ffffff" color="#000080">什么是线程.我们编写的程序大多数可以看成是单线程的.就是程序是按照一定的顺序来执行.如果我们使用线程的话,程序就会在我们创建线成的地方分叉,变成两个"程序"在执行.粗略的看来好象和子进程差不多的,其实不然.子进程是通过拷贝父进程的地址空间来执行的.而线程是通过共享程序代码来执行的,讲的通俗一点就是线程的相同的代码会被执行几次.使用线程的好处是可以节省资源,由于线程是通过共享代码的,所以没有进程调度那么复杂.</font></strong></p>
		<hr />
		<p>1.线程的创建和使用 </p>
		<p>线程的创建是用下面的几个函数来实现的. </p>
		<pre>#include &lt;pthread.h&gt;
                                                                                                                           
int pthread_create(pthread_t *thread,pthread_attr_t *attr,
 void *(*start_routine)(void *),void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread *thread,void **thread_return);
                                                                                                                           
</pre>
		<p>pthread_create创建一个线程,thread是用来表明创建线程的ID,attr指出线程创建时候的属性,我们用NULL来表明使用缺省属性.start_routine函数指针是线程创建成功後开始执行的函数,arg是这个函数的唯一一个参数.表明传递给start_routine的参数. pthrea d_exit函数和exit函数类似用来退出线程.这个函数结束线程,释放函数的资源,并在最後阻塞,直到其他线程使用pthread_join函数等待它.然後将*retval的值传递给**thread_ return.由于这个函数释放所以的函数资源,所以retval不能够指向函数的局部变量. pt hread_join和wait调用一样用来等待指定的线程.注意由于线程不同于进程.所以线程的退出一定要用pthread_exit而不是使用exit.否则整个程序会退出的. 下面我们使用一个实例来解释一下使用方法.在实践中,我们经常要备份一些文件.下面这个程序可以实现当前目录下的所有文件备份.备份後的後缀名为bak </p>
		<pre>#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;errno.h&gt;
#include &lt;pthread.h&gt;
#include &lt;dirent.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;sys/time.h&gt;
                                                                                                                            
#define  BUFFER 512
                                                                                                                            
struct copy_file {
int infile;
int outfile;
};
                                                                                                                            
void *copy(void *arg)
{
  int infile,outfile;
  int bytes_read,bytes_write,*bytes_copy_p;
  char buffer[BUFFER],*buffer_p;
  struct copy_file *file=(struct copy_file *)arg;
  infile=file-&gt;infile;
  outfile=file-&gt;outfile;
/* 因为线程退出时,所有的变量空间都要被释放,所以我们只好自己分配内存了 */
  if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) pthread_exit(NULL);
  bytes_read=bytes_write=0;
  *bytes_copy_p=0;
/* 还记得怎么拷贝文件吗  */
  while((bytes_read=read(infile,buffer,BUFFER))!=0)
   {
if((bytes_read==-1)&amp;&amp;(errno!=EINTR))break;
else if(bytes_read&gt;0)
        {
   buffer_p=buffer;
   while((bytes_write=write(outfile,buffer_p,bytes_read))!=0)
    {
 if((bytes_write==-1)&amp;&amp;(errno!=EINTR))break;
 else if(bytes_write==bytes_read)break;
 else if(bytes_write&gt;0)
  {
  buffer_p+=bytes_write;
  bytes_read-=bytes_write;
  }
    }
 if(bytes_write==-1)break;
 *bytes_copy_p+=bytes_read;
       }
   }
  close(infile);
  close(outfile);
  pthread_exit(bytes_copy_p);
}
                                                                                                                            
int main(int argc,char **argv)
{
 pthread_t *thread;
 struct copy_file *file;
 int byte_copy,*byte_copy_p,num,i,j;
 char filename[BUFFER];
 struct dirent **namelist;
 struct stat filestat;
/* 得到当前路径下面所有的文件(包含目录)的个数 */
 if((num=scandir(".",&amp;namelist,0,alphasort))&lt;0)
  {
fprintf(stderr,"Get File Num Error:%s\n\a",strerror(errno));
exit(1);
  }
/* 给线程分配空间,其实没有必要这么多的 */
 if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)||
    ((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL)
)
  {
fprintf(stderr,"Out Of Memory!\n\a");
exit(1);
  }
 for(i=0,j=0;i&lt;num;i++)
  {
memset(filename,'\0',BUFFER);
strcpy(filename,namelist[i]-&gt;d_name);
if(stat(filename,&amp;filestat)==-1)
 {
        fprintf(stderr,"Get File Information:%s\n\a",strerror(errno));
               exit(1);
        }
/* 我们忽略目录  */
if(!S_ISREG(filestat.st_mode))continue;
if((file[j].infile=open(filename,O_RDONLY))&lt;0)
 {
      fprintf(stderr,"Open %s  Error:%s\n\a",filename,strerror(errno));
          continue;
    }
strcat(filename,".bak");
       if((file[j].outfile=open(filename,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))&lt;0)
        {
            fprintf(stderr,"Creat %s  Error:%s\n\a",filename,strerror(errno));
            continue;
        }
/* 创建线程,进行文件拷贝  */
if(pthread_create(&amp;thread[j],NULL,copy,(void *)&amp;file[j])!=0)
 fprintf(stderr,"Create Thread[%d] Error:%s\n\a",i,strerror(errno));
j++;
 }
 byte_copy=0;
 for(i=0;i&lt;j;i++)
  {
/* 等待线程结束  */
if(pthread_join(thread[i],(void **)&amp;byte_copy_p)!=0)
 fprintf(stderr,"Thread[%d] Join Error:%s\n\a",
 i,strerror(errno));
else
        {
   if(bytes_copy_p==NULL)continue;
   printf("Thread[%d] Copy %d bytes\n\a",i,*byte_copy_p);
   byte_copy+=*byte_copy_p;
/* 释放我们在copy函数里面创建的内存 */
   free(byte_copy_p);
        }
  }
printf("Total Copy Bytes %d\n\a",byte_copy);
free(thread);
free(file);
exit(0);
}
                                                                                                                           
</pre>
		<p>2.线程的同步和互斥 </p>
		<pre>   还记得我们在Linux进程通信一篇中叙述的POSIX无名信号量吗?由于Linux不支持进
</pre>
		<p>程之间的无名信号量.所以我们在那个地方没有提供实例.不过Linux提供了线程之间的无名信号量.我们可以使用POSIX无名信号量来处理线程之间的资源共享.下面以一个实际例子来说明如何进行线程同步. </p>
		<pre>/* 下面的程序如果正常运行的话,应该输出5行Language C For Linux */
                                                                                                                            
/*  sem.c  */
#include &lt;pthread.h&gt;
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;string.h&gt;
                                                                                                                            
#ifdef USE_SEM
#include &lt;semaphore.h&gt;
sem_t res;
#endif
                                                                                                                           
void *thread_init(void *arg)
{
char *string="Language C For Linux\n";
int n,i;
n=strlen(string);
#ifdef USE_SEM
sem_wait(&amp;res);
#endif
for(i=0;i&lt;n;i++)
{
/* 为了更好的看到几个线程争夺stdout这个共享资源.我们在这个地方休息一下 */
 usleep(1000);
 write(STDOUT_FILENO,&amp;string[i],sizeof(char));
}
                                                                                                                           
#ifdef USE_SEM
 sem_post(&amp;res);
#endif
                                                                                                                           
pthread_exit(NULL);
}
                                                                                                                            
int main()
</pre>
		<p>{ </p>
		<pre>pthread_t thread[5];
int i,n;
n=sizeof(thread)/sizeof(thread[0]);
                                                                                                                           
#ifdef USE_SEM
/* 这里我们的第一个参数是0表示只在一个进程内部使用,第二个参数为1
   表示我们只有一个信号量(一个标准输出)
   请参考POSIX无名信号量
*/
sem_init(&amp;res,0,1);
#endif
                                                                                                                           
for(i=0;i&lt;n;i++)
 pthread_create(&amp;thread[i],NULL,thread_init,NULL);
for(i=0;i&lt;n;i++)
 pthread_join(thread[i],NULL);
return(0);
}
                                                                                                                           
</pre>
		<p>如果我们没有定义USE_SEM的来编译这个程序.运行以後的结果是一个没有按照我们希望的结果输出的. </p>
		<pre>$ gcc -O2 -Wall -o sem sem.c -lpthread
$ ./sem
                                                                                                                           
</pre>
		<p>这个程序的输出由于我们没有很好的控制线程之间的同步,几个线程会去争夺标准输出这个共享资源,而倒置我们的程序输出结果是杂乱无章的. </p>
		<p>如果我们进行了线程的同步,也就事定义了USE_SEM宏.程序才会按照我们设想的方式运行 . </p>
		<pre>$ gcc -O2 -Wall -DUSE_SEM -o sem sem.c -lpthread -WALL
$ ./sem
                                                                                                                           
</pre>
		<p>进行线程同步的第二种办法是使用互斥锁(mutex) </p>
		<pre>        #include &lt;pthread.h&gt;
                                                                                                                           
        int pthread_mutex_init (pthread_mutex_t *mutex,
             const pthread_mutexattr_t *attr);
        int pthread_mutex_destroy (pthread_mutex_t *mutex);
        int pthread_mutex_lock (pthread_mutex_t *mutex);
        int pthread_mutex_trylock (pthread_mutex_t *mutex);
        int pthread_mutex_unlock (pthread_mutex_t *mutex);
                                                                                                                           
</pre>
		<p>如果我们要使用互斥锁我们首先必须声明一个pthread_mutex_t的结构.然後要么调用 p thread_mutex_init对这个互斥锁进行初始化,要么我们在定义这个互斥锁的时候使用 P THREAD_MUTEX_INITILIZER进行初始化. 一旦我们创建好了互斥锁我们就可以进行对锁的锁住和解锁操作. 调用pthread_mutex_ lock会去锁住互斥锁,如果互斥锁被其它线程锁住了,线程会被祖塞. 直到这个互斥锁被解锁.调用pthread_mutex_unlock可以释放被锁住的互斥锁. 同时会唤醒那些正在等待这个互斥锁解锁的线程.如果我们不希望线程被阻塞. 我们可以调用pthread_mutex_trylo ck函数,如果互斥锁没有被其它线程锁住. 这个函数会去锁住互斥锁,否则这个函数立即返回.同时返回错误代码为EBUSY的错误. </p>
		<pre>#include &lt;pthread.h&gt;
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;string.h&gt;
                                                                                                                            
#ifdef USE_SEM
#include &lt;semaphore.h&gt;
sem_t res;
#elif  USE_MUTEX
#ifdef USE_STATIC
pthread_mutex_t mutex_lock=PTHREAD_MUTEX_INITIALIZER;
#else
pthread_mutex_t mutex_lock;
#endif
#endif
                                                                                                                            
void *thread_init(void *arg)
{
char *string="Language C For Linux\n";
int n,i;
n=strlen(string);
#ifdef USE_SEM
sem_wait(&amp;res);
#elif   USE_MUTEX
pthread_mutex_lock(&amp;mutex_lock);
#endif
for(i=0;i&lt;n;i++)
{
 usleep(1000);
 write(STDOUT_FILENO,&amp;string[i],sizeof(char));
}
#ifdef USE_SEM
sem_post(&amp;res);
#elif  USE_MUTEX
pthread_mutex_unlock(&amp;mutex_lock);
#endif
pthread_exit(NULL);
}
                                                                                                                            
int main()
{
pthread_t thread[5];
int i,n;
n=sizeof(thread)/sizeof(thread[0]);
#ifdef USE_SEM
sem_init(&amp;res,0,1);
#elif  USE_MUTEX
#ifdef USE_STATIC
pthread_mutex_init(&amp;mutex_lock,NULL);
#endif
#endif
for(i=0;i&lt;n;i++)
 pthread_create(&amp;thread[i],NULL,thread_init,NULL);
for(i=0;i&lt;n;i++)
 pthread_join(thread[i],NULL);
return(0);
}
                                                                                                                           
</pre>
		<p>这个程序是上面的程序的改进.我们使用了互斥锁来进行线程的同步操作.在这个程序中我们使用了2中方法来进行互斥锁的初始化.一个是使用静态的初始化,一个是使用函数的初始话.可以分别使用下面的命令来进行编译. </p>
		<p>使用函数初始化 </p>
		<pre>$gcc -O2 -Wall -DUSE_MUTEX mutex mutex.c -lpthread
$./mutex
                                                                                                                           
</pre>
		<p>使用静态变量初始化 </p>
		<pre>$gcc -O2 -Wall -DUSE_MUTEX -DUSE_STATIC mutext mutex.c -lpthread
$./mutex
                                                                                                                           
</pre>
		<p>3.线程的条件变量 </p>
		<p>假设线程必须等待某个包含全局变量集合的一个测试条件(比如有2个全局变量x,y.线程必须在x,y满足一定的条件的时候才执行).由于使用全局变量对于线程来说是临界区的东西,所以多全局变量的访问要进行互斥锁的操作.线程的条件变量为线程提供了一种等待包含这些全局变量的测试条件.不管什么时候,线程改变了这些全局变量的一个,线程就会条件变量上发出信号,通知阻塞的线程,条件改变了.这个信号会唤醒在等待条件的线程.当一个阻塞的线程收到信号以後,必须测试条件是否成立,因为信号只是表示全局变量改变了 ,并不意味着条件一定会成立.所以线程一定要测试条件是否成立.由于线程测试的时候要访问全局变量,所以线程首先要使用互斥锁.如果条件不成立,线程应该要释放互斥锁同时阻塞自己.而且互斥要在是否互斥锁之间释放,以便其它线程可以去访问全局变量.并可以改变全局变量的值,锁的释放和线程的阻塞必须是原子操作.这样其它的线程就不会在线程释放互斥锁和阻塞之前修改全局变量. </p>
		<p>下面我们介绍一样线程条件变量的函数 </p>
		<pre>       #include &lt;pthread.h&gt;
                                                                                                                           
       int pthread_cond_init (pthread_cond_t *cond,
            const pthread_condattr_t *arrt);
       int pthread_cond_destroy (pthread_cond_t *cond);
       int pthread_cond_wait (pthread_cond_t *cond,
            pthread_mutex_t *mutex);
       int pthread_cond_timedwait (pthread_cond_t *cond,
            pthread_mutex_t *mutex, const struct timespec *abstime);
       int pthread_cond_signal (pthread_cond_t *cond);
       int pthread_cond_broadcast (pthread_cond_t *cond);
                                                                                                                           
</pre>
		<p>pthread_cond_init 和pthread_mutex_init一样,可以初始化条件变量.当然我们也可以使用静态的初始化.pthread_cond_destroy用来删除信号量.pthread_cond_wait用来阻塞线程直到被pthread_cond_signal或者是pthread_cond_broadcast唤醒. </p>
		<p>pthread_cond_timedwait也用来阻塞线程不过在时间abstime超时以後返回. </p>
		<p>为了很好的说明互斥锁,我们使用一个实例来进行说明. 假设cond表示条件变量.mutex表示互斥锁.x==y表示我们要满足的测试条件.我们可以有下面的伪代码: </p>
		<pre>#include &lt;pthread.h&gt;
                                                                                                                           
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  cond =PTHREAD_COND_INITIALIZER;
static int x = 1;
staitc int y = 2;
                                                                                                                           
/* 下面的这个代码用来检测条件x==y是否成立. */
1) pthread_mutex_lock(&amp;mutex);
2) while(x!=y)
3) pthread_cond_wait(&amp;cond,&amp;mutex);
4) .... /* 进行我们的操作 */
5) pthread_mutex_unlock(&amp;mutex);
                                                                                                                           
/* 下面的代码用来改变x,y的值,使它们去满足一定的条件 */
6) pthread_mutex_lock(&amp;mutex);
7) x++;
8) pthread_cond_signal(&amp;cond);
9) pthread_mutex_unlock(&amp;mutex);
                                                                                                                           
</pre>
		<p>我们来分析一下上面的伪代码. </p>
		<p>我们考虑一个线程从1)开始执行,一个从6)开始执行.如果线程一首先开始执行了1)锁住了 mutex然後执行了2)进行条件测试.由于我们的x!=y成立,然後线程执行3)线程这个时候阻塞了.按照线程条件变量的要求,线程在阻塞之前隐式的(没有调用pthread_mutex_unlock) 来释放互斥锁.这个时候线程二开始执行6).由于线程一隐式的释放了互斥锁,所以线程二获得了互斥锁.可以执行7)接着执行8).这个时候线程二唤醒线程一,同时线程二继续执行. 线程一接收到了信号,由于线程一在pthread_cond_wait中隐式的释放了互斥锁,所以这个时候线程一又隐式的去锁住互斥锁不过这个时候互斥锁还被线程二拥有,所以线程一在隐式的锁住互斥锁处阻塞.直到线程二执行完9)以後,线程一才从3返回,由于线程一不知道条件是否成立,所以线程继续执行2)测试条件.条件成立,线程一开始执条件是否成立,所以线程继续执行2)测试条件.条件成立,线程一开始执行其它操作. 由于我们隐式的锁住了互斥锁,所以最後要释放互斥锁. 从上面的分析和从pthread_cond_wait的原型我们可以"猜测"一下pthread_cond_wait所执行的操作 </p>
		<pre> /* 注意实际情况肯定不是这样的,我这样写只是我们更容易离解一些 */
  ...
/* 从pthread_cond_wait中隐式的释放互斥锁 */
  1) pthread_mutex_unlock(&amp;mutex);
  ... /* 阻塞 */
/* 从pthread_cond_wait中隐式的锁住互斥锁 */
  2) pthread_mutex_lock(&amp;mutex);
  ...
</pre>
		<p>
				<br />转自 水木清华 </p>
		<div class="printfooter">Retrieved from "<a href="http://wiki.chinaunix.net/index.php/Zhuan_c7">http://wiki.chinaunix.net/index.php/Zhuan_c7</a>"</div>
		<!-- end content -->
<img src ="http://www.cnitblog.com/guopingleee/aggbug/38162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2007-12-27 14:13 <a href="http://www.cnitblog.com/guopingleee/archive/2007/12/27/38162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>