1. )Linux程序设计入门--线程操作
  2. 前言:Linux下线程的创建
  3. 介绍在Linux下线程的创建和基本的使用. Linux下的线程是一个非常复杂的问题,由
  4. 于我对线程的学习不时很好,我在这里只是简单的介绍线程的创建和基本的使用,关于线
  5. 程的高级使用(如线程的属性,线程的互斥,线程的同步等等问题)可以参考我后面给出的
  6. 资料. 现在关于线程的资料在网络上可以找到许多英文资料,后面我罗列了许多链接,对
  7. 线程的高级属性感兴趣的话可以参考一下. 等到我对线程的了解比较深刻的时候,我回来
  8. 完成这篇文章.如果您对线程了解的详尽我也非常高兴能够由您来完善.
  9. 先介绍什么是线程.我们编写的程序大多数可以看成是单线程的.就是程序是按照一定的
  10. 顺序来执行.如果我们使用线程的话,程序就会在我们创建线成的地方分叉,变成两个"程
  11. 序"在执行.粗略的看来好象和子进程差不多的,其实不然.子进程是通过拷贝父进程的地
  12. 址空间来执行的.而线程是通过共享程序代码来执行的,讲的通俗一点就是线程的相同的
  13. 代码会被执行几次.使用线程的好处是可以节省资源,由于线程是通过共享代码的,所以没
  14. 有进程调度那么复杂.
  15. 线程的创建和使用
  16. 线程的创建是用下面的几个函数来实现的.
  17. #include <pthread.h>;
  18. int pthread_create(pthread_t *thread,pthread_attr_t *attr,
  19. void *(*start_routine)(void *),void *arg);
  20. void pthread_exit(void *retval);
  21. int pthread_join(pthread *thread,void **thread_return);
  22. pthread_create创建一个线程,thread是用来表明创建线程的ID,attr指出线程创建时候
  23. 的属性,我们用NULL来表明使用缺省属性.start_routine函数指针是线程创建成功后开始
  24. 执行的函数,arg是这个函数的唯一一个参数.表明传递给start_routine的参数. pthrea
  25. d_exit函数和exit函数类似用来退出线程.这个函数结束线程,释放函数的资源,并在最后
  26. 阻塞,直到其他线程使用pthread_join函数等待它.然后将*retval的值传递给**thread_
  27. return.由于这个函数释放所以的函数资源,所以retval不能够指向函数的局部变量. pt
  28. hread_joinwait调用一样用来等待指定的线程. 下面我们使用一个实例来解释一下使
  29. 用方法.在实践中,我们经常要备份一些文件.下面这个程序可以实现当前目录下的所有文
  30. 件备份.备份后的后缀名为bak
  31. #include <stdio.h>;
  32. #include <unistd.h>;
  33. #include <stdlib.h>;
  34. #include <string.h>;
  35. #include <errno.h>;
  36. #include <pthread.h>;
  37. #include <dirent.h>;
  38. #include <fcntl.h>;
  39. #include <sys/types.h>;
  40. #include <sys/stat.h>;
  41. #include <sys/time.h>;
  42. #define BUFFER 512
  43. struct copy_file {
  44. int infile;
  45. int outfile;
  46. };
  47. void *copy(void *arg)
  48. {
  49. int infile,outfile;
  50. int bytes_read,bytes_write,*bytes_copy_p;
  51. char buffer[BUFFER],*buffer_p;
  52. struct copy_file *file=(struct copy_file *)arg;
  53. infile=file->;infile;
  54. outfile=file->;outfile;
  55. /* 因为线程退出时,所有的变量空间都要被释放,所以我们只好自己分配内存了 */
  56. if((bytes_copy_p=(int *)malloc(sizeof(int)))==NULL) pthread_exit(NULL);
  57. bytes_read=bytes_write=;
  58. *bytes_copy_p=;
  59. /* 还记得怎么拷贝文件吗 */
  60. )
  61. {
  62. )&&(errno!=EINTR))break;
  63. )
  64. {
  65. buffer_p=buffer;
  66. )
  67. {
  68. )&&(errno!=EINTR))break;
  69. else if(bytes_write==bytes_read)break;
  70. )
  71. {
  72. buffer_p+=bytes_write;
  73. bytes_read-=bytes_write;
  74. }
  75. }
  76. )break;
  77. *bytes_copy_p+=bytes_read;
  78. }
  79. }
  80. close(infile);
  81. close(outfile);
  82. pthread_exit(bytes_copy_p);
  83. }
  84. int main(int argc,char **argv)
  85. {
  86. pthread_t *thread;
  87. struct copy_file *file;
  88. int byte_copy,*byte_copy_p,num,i,j;
  89. char filename[BUFFER];
  90. struct dirent **namelist;
  91. struct stat filestat;
  92. /* 得到当前路径下面所有的文件(包含目录)的个数 */
  93. ,alphasort))<)
  94. {
  95. fprintf(stderr,"Get File Num Error:%s\n\a",strerror(errno));
  96. exit();
  97. }
  98. /* 给线程分配空间,其实没有必要这么多的 */
  99. if(((thread=(pthread_t *)malloc(sizeof(pthread_t)*num))==NULL)||
  100. ((file=(struct copy_file *)malloc(sizeof(struct copy_file)*num))==NULL)
  101. )
  102. {
  103. fprintf(stderr,"Out Of Memory!\n\a");
  104. exit();
  105. }
  106. ,j=;i<num;i++)
  107. {
  108. memset(filename,'\0',BUFFER);
  109. strcpy(filename,namelist->;d_name);
  110. )
  111. {
  112. fprintf(stderr,"Get File Information:%s\n\a",strerror(errno));
  113. exit();
  114. }
  115. /* 我们忽略目录 */
  116. if(!S_ISREG(filestat.st_mode))continue;
  117. )
  118. {
  119. fprintf(stderr,"Open %s Error:%s\n\a",filename,strerror(errno));
  120. continue;
  121. }
  122. strcat(filename,".bak");
  123. if((file[j].outfile=open(filename,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR))
  124. <)
  125. {
  126. fprintf(stderr,"Creat %s Error:%s\n\a",filename,strerror(errno
  127. ));
  128. continue;
  129. }
  130. /* 创建线程,进行文件拷贝 */
  131. )
  132. fprintf(stderr,"Create Thread[%d] Error:%s\n\a",i,strerror(errno));
  133. j++;
  134. }
  135. byte_copy=;
  136. ;i<j;i++)
  137. {
  138. /* 等待线程结束 */
  139. )
  140. fprintf(stderr,"Thread[%d] Join Error:%s\n\a",
  141. i,strerror(errno));
  142. else
  143. {
  144. if(bytes_copy_p==NULL)continue;
  145. printf("Thread[%d] Copy %d bytes\n\a",i,*byte_copy_p);
  146. byte_copy+=*byte_copy_p;
  147. /* 释放我们在copy函数里面创建的内存 */
  148. free(byte_copy_p);
  149. }
  150. }
  151. printf("Total Copy Bytes %d\n\a",byte_copy);
  152. free(thread);
  153. free(file);
  154. exit();
  155. }
  156. 线程的介绍就到这里了,关于线程的其他资料可以查看下面这写链接.
  157. Getting Started With POSIX Threads
  158. The LinuxThreads library
  159. [size=][color=red]<未完待续>;[/color][/size]
  160. 007xiong 回复于:-- ::
  161. [size=][color=red]续前贴[/color][/size]

8)Linux程序设计入门--线程操作的更多相关文章

  1. 3)Linux程序设计入门--文件操作

    )Linux程序设计入门--文件操作 Linux下文件的操作 前言: 我们在这一节将要讨论linux下文件操作的各个函数. 文件的创建和读写 文件的各个属性 目录文件的操作 管道文件 .文件的创建和读 ...

  2. 6)Linux程序设计入门--消息管理

    )Linux程序设计入门--消息管理 前言:Linux下的进程通信(IPC) Linux下的进程通信(IPC) POSIX无名信号量 System V信号量 System V消息队列 System V ...

  3. 5)Linux程序设计入门--信号处理

    )Linux程序设计入门--信号处理 Linux下的信号事件 前言:这一章我们讨论一下Linux下的信号处理函数. Linux下的信号处理函数: 信号的产生 信号的处理 其它信号函数 一个实例 .信号 ...

  4. 2)Linux程序设计入门--进程介绍

    )Linux程序设计入门--进程介绍 Linux下进程的创建 前言: 这篇文章是用来介绍在Linux下和进程相关的各个概念.我们将会学到: 进程的概念 进程的身份 进程的创建 守护进程的创建 .进程的 ...

  5. 1)Linux程序设计入门--基础知识

    )Linux程序设计入门--基础知识 Linux下C语言编程基础知识 前言: 这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将 会学到以下内容: 源程序编译 Makef ...

  6. 7)Linux程序设计入门--网络编程

    )Linux程序设计入门--网络编程 Linux系统的一个主要特点是他的网络功能非常强大.随着网络的日益普及,基于网络的 应用也将越来越多. 在这个网络时代,掌握了Linux的网络编程技术,将令每一个 ...

  7. 4)linux程序设计入门--时间概念

    )程序设计入门--时间概念 前言:Linux下的时间概念 这一章我们学习Linux的时间表示和计算函数 时间的表示 时间的测量 计时器的使用 .时间表示 在程序当中,我们经常要输出系统当前的时间,比如 ...

  8. (大数据工程师学习路径)第一步 Linux 基础入门----文件系统操作与磁盘管理

    介绍 本节的文件系统操作的内容十分简单,只会包含几个命令的几个参数的讲解,但掌握这些也将对你在学习后续其他内容的过程中有极大帮助. 因为本课程的定位为入门基础,尽快上手,故没有打算涉及太多理论内容,前 ...

  9. Linux基础入门-文件系统操作与磁盘管理

    一.简单文件系统操作: df (-h) 查看磁盘容量: rootfs作为系统启动时内核载入内存之后,在挂载真正的磁盘之前的一个临时文件系统: /dev/sda2 对应主机硬盘的分区,后面的a表示第几块 ...

随机推荐

  1. pdb-不需要IDE也能调试

    python中有个pdb模块,使python代码也可以像gdb那样进行调试,一般情况下pdb模块可以在代码内直接使用,也可以通过命令行参数的形式添加该模块进行调试(python -m pdb file ...

  2. Linux的权限对于文件与目录的意义

    权限对文件: r:可读取此文件的实际内容. w:可以编辑.新增或者是修改该文件的内容(但不含删除该文件),如果没有r权限,无法w. x :该文件具有被系统执行的权限.可以删除. 权限对目录: r:re ...

  3. 使用matlab表示“段数不确定”的分段函数

    示例函数: 分段函数f(x)的段数为数组a的长度减1,在表达f(x)时,不能直接使用a的长度5-1=4. 方法1: 先计算每个间隔点的函数值f(a2),f(a3),f(a4),再循环表示f(x). f ...

  4. Python全栈开发之7、模块和几种常见模块以及format知识补充

    一.模块的分类 Python流行的一个原因就是因为它的第三方模块数量巨大,我们编写代码不必从零开始重新造轮子,许多要用的功能都已经写好封装成库了,我们只要直接调用即可,模块分为内建模块.自定义的模块. ...

  5. loadrunner中controller 中scenario-> rendezvous灰色不可用的解决方法:

    1.首先确保lr_rendezvous("login");函数添加成功  Action() { web_set_max_html_param_len("2048" ...

  6. Codeforces Round #285 (Div. 1) B - Misha and Permutations Summation 康拓展开+平衡树

    思路:很裸的康拓展开.. 我的平衡树居然跑的比树状数组+二分还慢.. #include<bits/stdc++.h> #define LL long long #define fi fir ...

  7. mysql打印输出转csv格式

    1. mysql打印输出放在input.csv中 2. 执行该文件 <?php $str = file_get_contents("./input.csv"); $str = ...

  8. 【JAVAWEB学习笔记】网上商城实战1:环境搭建和完成用户模块

    今日任务 完成用户模块的功能 1.1      网上商城的实战: 1.1.1    演示网上商城的功能: 1.1.2    制作目的: 灵活运用所学知识完成商城实战. 1.1.3    数据库分析和设 ...

  9. Linux-数据库2

    表记录的操作 增 1.插入一条记录 语法:insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......); ...

  10. ZXing.Net.Mobile无法识别较大的条码

    ZXing.Net.Mobile无法识别较大的条码 在Xamarin项目中,使用ZXing.Net.Mobile实现条码扫描时,可能会出现无法顺利识别较大的条码,而可以正常识别较小的条码.这是由于ZX ...