<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[Linux程序设计入门--线程操作(转）]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[生活笔记]]></category>
<pubDate>Thu, 03 Jul 2008 02:21:21 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	Linux程序设计入门--线程操作 <br/>前言:Linux下线程的创建 <br/>介绍在Linux下线程的创建和基本的使用. Linux下的线程是一个非常复杂的问题,由 <br/>于我对线程的学习不时很好,我在这里只是简单的介绍线程的创建和基本的使用,关于线 <br/>程的高级使用(如线程的属性,线程的互斥,线程的同步等等问题)可以参考我后面给出的 <br/>资料. 现在关于线程的资料在网络上可以找到许多英文资料,后面我罗列了许多链接,对 <br/>线程的高级属性感兴趣的话可以参考一下. 等到我对线程的了解比较深刻的时候,我回来 <br/>完成这篇文章.如果您对线程了解的详尽我也非常高兴能够由您来完善. <br/>先介绍什么是线程.我们编写的程序大多数可以看成是单线程的.就是程序是按照一定的 <br/>顺序来执行.如果我们使用线程的话,程序就会在我们创建线成的地方分叉,变成两个&quot;程 <br/>序&quot;在执行.粗略的看来好象和子进程差不多的,其实不然.子进程是通过拷贝父进程的地 <br/>址空间来执行的.而线程是通过共享程序代码来执行的,讲的通俗一点就是线程的相同的 <br/>代码会被执行几次.使用线程的好处是可以节省资源,由于线程是通过共享代码的,所以没 <br/>有进程调度那么复杂. <br/><br/>线程的创建和使用 <br/>线程的创建是用下面的几个函数来实现的. <br/><br/>view plainprint?<br/>#include &lt;pthread.h&gt;&nbsp;&nbsp; <br/>int pthread_create(pthread_t *thread,pthread_attr_t *attr,&nbsp;&nbsp; <br/>void *(*start_routine)(void *),void *arg);&nbsp;&nbsp; <br/>void pthread_exit(void *retval);&nbsp;&nbsp; <br/>int pthread_join(pthread *thread,void **thread_return);&nbsp;&nbsp; <br/>#include &lt;pthread.h&gt; <br/>int pthread_create(pthread_t *thread,pthread_attr_t *attr, <br/>void *(*start_routine)(void *),void *arg); <br/>void pthread_exit(void *retval); <br/>int pthread_join(pthread *thread,void **thread_return); <br/><br/>pthread_create创建一个线程,thread是用来表明创建线程的ID,attr指出线程创建时候 <br/>的属性,我们用NULL来表明使用缺省属性.start_routine函数指针是线程创建成功后开始 <br/>执行的函数,arg是这个函数的唯一一个参数.表明传递给start_routine的参数. pthrea <br/>d_exit函数和exit函数类似用来退出线程.这个函数结束线程,释放函数的资源,并在最后 <br/>阻塞,直到其他线程使用pthread_join函数等待它.然后将*retval的值传递给**thread_ <br/>return.由于这个函数释放所以的函数资源,所以retval不能够指向函数的局部变量. pt <br/>hread_join和wait调用一样用来等待指定的线程. 下面我们使用一个实例来解释一下使 <br/>用方法.在实践中,我们经常要备份一些文件.下面这个程序可以实现当前目录下的所有文 <br/>件备份.备份后的后缀名为bak <br/><br/>view plainprint?<br/>#include &lt;stdio.h&gt;&nbsp;&nbsp; <br/>#include &lt;unistd.h&gt;&nbsp;&nbsp; <br/>#include &lt;stdlib.h&gt;&nbsp;&nbsp; <br/>#include &lt;string.h&gt;&nbsp;&nbsp; <br/>#include &lt;errno.h&gt;&nbsp;&nbsp; <br/>#include &lt;pthread.h&gt;&nbsp;&nbsp; <br/>#include &lt;dirent.h&gt;&nbsp;&nbsp; <br/>#include &lt;fcntl.h&gt;&nbsp;&nbsp; <br/>#include &lt;sys/types.h&gt;&nbsp;&nbsp; <br/>#include &lt;sys/stat.h&gt;&nbsp;&nbsp; <br/>#include &lt;sys/time.h&gt;&nbsp;&nbsp; <br/>#define BUFFER 512&nbsp;&nbsp; <br/>struct copy_file {&nbsp;&nbsp; <br/>int infile;&nbsp;&nbsp; <br/>int outfile;&nbsp;&nbsp; <br/>};&nbsp;&nbsp; <br/>void *copy(void *arg)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>int infile,outfile;&nbsp;&nbsp; <br/>int bytes_read,bytes_write,*bytes_copy_p;&nbsp;&nbsp; <br/>char buffer[BUFFER],*buffer_p;&nbsp;&nbsp; <br/>struct copy_file *file=(struct copy_file *)arg;&nbsp;&nbsp; <br/>infile=file-&gt;infile;&nbsp;&nbsp; <br/>outfile=file-&gt;outfile;&nbsp;&nbsp; <br/>/* 因为线程退出时,所有的变量空间都要被释放,所以我们只好自己分配内存了 */&nbsp;&nbsp; <br/>if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) pthread_exit(NULL);&nbsp;&nbsp; <br/>bytes_read=bytes_write=0;&nbsp;&nbsp; <br/>*bytes_copy_p=0;&nbsp;&nbsp; <br/>/* 还记得怎么拷贝文件吗 */&nbsp;&nbsp; <br/>while((bytes_read=read(infile,buffer,BUFFER))!=0)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>if((bytes_read==-1)&amp;&amp;(errno!=EINTR))break;&nbsp;&nbsp; <br/>else if(bytes_read&gt;0)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>buffer_p=buffer;&nbsp;&nbsp; <br/>while((bytes_write=write(outfile,buffer_p,bytes_read))!=0)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>if((bytes_write==-1)&amp;&amp;(errno!=EINTR))break;&nbsp;&nbsp; <br/>else if(bytes_write==bytes_read)break;&nbsp;&nbsp; <br/>else if(bytes_write&gt;0)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>buffer_p+=bytes_write;&nbsp;&nbsp; <br/>bytes_read-=bytes_write;&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>if(bytes_write==-1)break;&nbsp;&nbsp; <br/>*bytes_copy_p+=bytes_read;&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>close(infile);&nbsp;&nbsp; <br/>close(outfile);&nbsp;&nbsp; <br/>pthread_exit(bytes_copy_p);&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>int main(int argc,char **argv)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>pthread_t *thread;&nbsp;&nbsp; <br/>struct copy_file *file;&nbsp;&nbsp; <br/>int byte_copy,*byte_copy_p,num,i,j;&nbsp;&nbsp; <br/>char filename[BUFFER];&nbsp;&nbsp; <br/>struct dirent **namelist;&nbsp;&nbsp; <br/>struct stat filestat;&nbsp;&nbsp; <br/>/* 得到当前路径下面所有的文件(包含目录)的个数 */&nbsp;&nbsp; <br/>if((num=scandir(&quot;.&quot;,&amp;namelist,0,alphasort))&lt;0)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>fprintf(stderr,&quot;Get File Num Error:%s&#92;n&#92;a&quot;,strerror(errno));&nbsp;&nbsp; <br/>exit(1);&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>/* 给线程分配空间,其实没有必要这么多的 */&nbsp;&nbsp; <br/>if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)&#124;&#124;&nbsp;&nbsp; <br/>((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL)&nbsp;&nbsp; <br/>)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>fprintf(stderr,&quot;Out Of Memory!&#92;n&#92;a&quot;);&nbsp;&nbsp; <br/>exit(1);&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>for(i=0,j=0;i&lt;num;i++)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>memset(filename,&#039;&#92;0&#039;,BUFFER);&nbsp;&nbsp; <br/>strcpy(filename,namelist[i]-&gt;d_name);&nbsp;&nbsp; <br/>if(stat(filename,&amp;filestat)==-1)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>fprintf(stderr,&quot;Get File Information:%s&#92;n&#92;a&quot;,strerror(errno));&nbsp;&nbsp; <br/>exit(1);&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>/* 我们忽略目录 */&nbsp;&nbsp; <br/>if(!S_ISREG(filestat.st_mode))continue;&nbsp;&nbsp; <br/>if((file[j].infile=open(filename,O_RDONLY))&lt;0)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>fprintf(stderr,&quot;Open %s Error:%s&#92;n&#92;a&quot;,filename,strerror(errno));&nbsp;&nbsp; <br/>continue;&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>strcat(filename,&quot;.bak&quot;);&nbsp;&nbsp; <br/>if((file[j].outfile=open(filename,O_WRONLY&#124;O_CREAT,S_IRUSR&#124;S_IWUSR))&nbsp;&nbsp; <br/>&lt;0)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>fprintf(stderr,&quot;Creat %s Error:%s&#92;n&#92;a&quot;,filename,strerror(errno&nbsp;&nbsp; <br/>));&nbsp;&nbsp; <br/>continue;&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>/* 创建线程,进行文件拷贝 */&nbsp;&nbsp; <br/>if(pthread_create(&amp;thread[j],NULL,copy,(void *)&amp;file[j])!=0)&nbsp;&nbsp; <br/>fprintf(stderr,&quot;Create Thread[%d] Error:%s&#92;n&#92;a&quot;,i,strerror(errno));&nbsp;&nbsp; <br/>j++;&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>byte_copy=0;&nbsp;&nbsp; <br/>for(i=0;i&lt;j;i++)&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>/* 等待线程结束 */&nbsp;&nbsp; <br/>if(pthread_join(thread[i],(void **)&amp;byte_copy_p)!=0)&nbsp;&nbsp; <br/>fprintf(stderr,&quot;Thread[%d] Join Error:%s&#92;n&#92;a&quot;,&nbsp;&nbsp; <br/>i,strerror(errno));&nbsp;&nbsp; <br/>else&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>if(bytes_copy_p==NULL)continue;&nbsp;&nbsp; <br/>printf(&quot;Thread[%d] Copy %d bytes&#92;n&#92;a&quot;,i,*byte_copy_p);&nbsp;&nbsp; <br/>byte_copy+=*byte_copy_p;&nbsp;&nbsp; <br/>/* 释放我们在copy函数里面创建的内存 */&nbsp;&nbsp; <br/>free(byte_copy_p);&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>printf(&quot;Total Copy Bytes %d&#92;n&#92;a&quot;,byte_copy);&nbsp;&nbsp; <br/>free(thread);&nbsp;&nbsp; <br/>free(file);&nbsp;&nbsp; <br/>exit(0);&nbsp;&nbsp; <br/>}&nbsp;&nbsp; <br/>#include &lt;stdio.h&gt; <br/>#include &lt;unistd.h&gt; <br/>#include &lt;stdlib.h&gt; <br/>#include &lt;string.h&gt; <br/>#include &lt;errno.h&gt; <br/>#include &lt;pthread.h&gt; <br/>#include &lt;dirent.h&gt; <br/>#include &lt;fcntl.h&gt; <br/>#include &lt;sys/types.h&gt; <br/>#include &lt;sys/stat.h&gt; <br/>#include &lt;sys/time.h&gt; <br/>#define BUFFER 512 <br/>struct copy_file { <br/>int infile; <br/>int outfile; <br/>}; <br/>void *copy(void *arg) <br/>{ <br/>int infile,outfile; <br/>int bytes_read,bytes_write,*bytes_copy_p; <br/>char buffer[BUFFER],*buffer_p; <br/>struct copy_file *file=(struct copy_file *)arg; <br/>infile=file-&gt;infile; <br/>outfile=file-&gt;outfile; <br/>/* 因为线程退出时,所有的变量空间都要被释放,所以我们只好自己分配内存了 */ <br/>if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) pthread_exit(NULL); <br/>bytes_read=bytes_write=0; <br/>*bytes_copy_p=0; <br/>/* 还记得怎么拷贝文件吗 */ <br/>while((bytes_read=read(infile,buffer,BUFFER))!=0) <br/>{ <br/>if((bytes_read==-1)&amp;&amp;(errno!=EINTR))break; <br/>else if(bytes_read&gt;0) <br/>{ <br/>buffer_p=buffer; <br/>while((bytes_write=write(outfile,buffer_p,bytes_read))!=0) <br/>{ <br/>if((bytes_write==-1)&amp;&amp;(errno!=EINTR))break; <br/>else if(bytes_write==bytes_read)break; <br/>else if(bytes_write&gt;0) <br/>{ <br/>buffer_p+=bytes_write; <br/>bytes_read-=bytes_write; <br/>} <br/>} <br/>if(bytes_write==-1)break; <br/>*bytes_copy_p+=bytes_read; <br/>} <br/>} <br/>close(infile); <br/>close(outfile); <br/>pthread_exit(bytes_copy_p); <br/>} <br/>int main(int argc,char **argv) <br/>{ <br/>pthread_t *thread; <br/>struct copy_file *file; <br/>int byte_copy,*byte_copy_p,num,i,j; <br/>char filename[BUFFER]; <br/>struct dirent **namelist; <br/>struct stat filestat; <br/>/* 得到当前路径下面所有的文件(包含目录)的个数 */ <br/>if((num=scandir(&quot;.&quot;,&amp;namelist,0,alphasort))&lt;0) <br/>{ <br/>fprintf(stderr,&quot;Get File Num Error:%s&#92;n&#92;a&quot;,strerror(errno)); <br/>exit(1); <br/>} <br/>/* 给线程分配空间,其实没有必要这么多的 */ <br/>if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)&#124;&#124; <br/>((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL) <br/>) <br/>{ <br/>fprintf(stderr,&quot;Out Of Memory!&#92;n&#92;a&quot;); <br/>exit(1); <br/>} <br/><br/>for(i=0,j=0;i&lt;num;i++) <br/>{ <br/>memset(filename,&#039;&#92;0&#039;,BUFFER); <br/>strcpy(filename,namelist[i]-&gt;d_name); <br/>if(stat(filename,&amp;filestat)==-1) <br/>{ <br/>fprintf(stderr,&quot;Get File Information:%s&#92;n&#92;a&quot;,strerror(errno)); <br/>exit(1); <br/>} <br/>/* 我们忽略目录 */ <br/>if(!S_ISREG(filestat.st_mode))continue; <br/>if((file[j].infile=open(filename,O_RDONLY))&lt;0) <br/>{ <br/>fprintf(stderr,&quot;Open %s Error:%s&#92;n&#92;a&quot;,filename,strerror(errno)); <br/>continue; <br/>} <br/>strcat(filename,&quot;.bak&quot;); <br/>if((file[j].outfile=open(filename,O_WRONLY&#124;O_CREAT,S_IRUSR&#124;S_IWUSR)) <br/>&lt;0) <br/>{ <br/>fprintf(stderr,&quot;Creat %s Error:%s&#92;n&#92;a&quot;,filename,strerror(errno <br/>)); <br/>continue; <br/>} <br/>/* 创建线程,进行文件拷贝 */ <br/>if(pthread_create(&amp;thread[j],NULL,copy,(void *)&amp;file[j])!=0) <br/>fprintf(stderr,&quot;Create Thread[%d] Error:%s&#92;n&#92;a&quot;,i,strerror(errno)); <br/>j++; <br/>} <br/>byte_copy=0; <br/>for(i=0;i&lt;j;i++) <br/>{ <br/>/* 等待线程结束 */ <br/>if(pthread_join(thread[i],(void **)&amp;byte_copy_p)!=0) <br/>fprintf(stderr,&quot;Thread[%d] Join Error:%s&#92;n&#92;a&quot;, <br/>i,strerror(errno)); <br/>else <br/>{ <br/>if(bytes_copy_p==NULL)continue; <br/>printf(&quot;Thread[%d] Copy %d bytes&#92;n&#92;a&quot;,i,*byte_copy_p); <br/>byte_copy+=*byte_copy_p; <br/>/* 释放我们在copy函数里面创建的内存 */ <br/>free(byte_copy_p); <br/>} <br/>} <br/>printf(&quot;Total Copy Bytes %d&#92;n&#92;a&quot;,byte_copy); <br/>free(thread); <br/>free(file); <br/>exit(0); <br/>} <br/><br/>线程的介绍就到这里了,关于线程的其他资料可以查看下面这写链接. <br/>Getting Started With POSIX Threads <br/>
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] Linux程序设计入门--线程操作(转）]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>