一、多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程。基于进程的多任务处理是程序的并发执行。基于线程的多任务处理是同一程序的片段的并发执行。多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程,每个线程定义了一个单独的执行路径,C++ 不包含多线程应用程序的任何内置支持。相反,它完全依赖于操作系统来提供此功能

二、多线程的案例(以下案例都在windows qt 环境下编译运行)

1. 多线程实现

  1. #include <iostream>
  2. //#include <pthread.h>
  3. #include <time.h>
  4. #include "pthread.h"
  5. using namespace std;
  6. #define NUM_THREADS 5
  7. //c++ 中实现延时函数
  8. void delay(int sec)
  9. {
  10. time_t start_time, cur_time; // 变量声明
  11. time(&start_time);
  12. do {
  13. time(&cur_time);
  14. } while((cur_time - start_time) < sec );
  15. }
  16. void *say_hello(void *threadid){
  17. //对传入的参数进行强制类型转换
  18. int tid = *((unsigned short *)threadid);
  19. cout << "Hello Runoob! 线程ID, "<< tid << endl;
  20. pthread_exit(NULL);
  21. }
  22. int main(){
  23. //定义线程id变量
  24. pthread_t tids[NUM_THREADS];
  25. int indexes[NUM_THREADS];
  26. for(int i = 0;i < NUM_THREADS; ++i){
  27. cout << "main() : 创建线程, " << i << endl;
  28. indexes[i] = i;//先保存i的值
  29. int ret = pthread_create(&tids[i],NULL,say_hello,(void *)&indexes[i]);
  30. if(ret != 0){
  31. cout << "pthread_create error : error_code="<< ret << endl;
  32. }
  33. }
  34. delay(2);
  35. pthread_exit(NULL);
  36. return 0;
  37. }

上述案例使用pthread_create创建线程,参数可以传入线程入口地址,调用成功后直接进入线程入口函数,入口函数代码即为线程体,在线程体执行完毕后调用pthread_exit结束线程,main函数就是一主线程,在其创建的线程都是其子线程,子线程依附于主线程,若主线程提前结束,子线程也会退出,为了保证子线程能够正常退出,在main线程中执行了delay 动作保证子线程有足够的时间调度执行。

执行效果:

  1. main() : 创建线程, 0
  2. main() : 创建线程, 1
  3. Hello Runoob! 线程ID, 0
  4. main() : 创建线程, 2
  5. main() : 创建线程, 3
  6. Hello Runoob! 线程ID, 2
  7. main() : 创建线程, 4
  8. Hello Runoob! 线程ID, 1
  9. Hello Runoob! 线程ID, 3
  10. Hello Runoob! 线程ID, 4

2.线程的分离和链接

在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。线程的分离状态决定一个线程以什么样的方式来终止自己。在默认情况下线程是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以pthread_attr_t结构中的detachstate线程属性,让线程以分离状态启动.

代码如下:

  1. #include <iostream>
  2. using namespace std;
  3. #include <cstdlib>
  4. #include <pthread.h>
  5. #include <unistd.h>
  6. #include <windows.h>
  7. #define NUM_THREADS 5
  8. void *wait(void *t){
  9. int i;
  10. long tid;
  11. tid = (long)t;
  12. Sleep(1000);
  13. cout <<"Sleeping in thread"<< endl;
  14. cout <<"Thread with id: " << tid << "exiting ...!" << endl;
  15. pthread_exit(NULL);
  16. }
  17. int main(){
  18. int rc,i;
  19. pthread_t theads[NUM_THREADS];
  20. pthread_attr_t attr;
  21. void *status;
  22. //初始化并设置线程为可连接的(joinable)
  23. pthread_attr_init(&attr);
  24. pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
  25. for(i = 0; i < NUM_THREADS ; i ++){
  26. cout << "main() : creating thread: " << i <<endl;
  27. rc = pthread_create(&theads[i],NULL,wait,(void *)i);
  28. if(rc){
  29. cout << "Error:uable to create thread," << endl;
  30. exit(-1);
  31. }
  32. }
  33. //删除属性并等待其他线程
  34. pthread_attr_destroy(&attr);
  35. for(i = 0; i < NUM_THREADS; i ++){
  36. rc = pthread_join(theads[i],&status);
  37. if(rc){
  38. cout <<"Uable to join," << endl;
  39. exit(-1);
  40. }
  41. cout << "Main:completed thread id:" << i << endl;
  42. cout << "exiting with status :" << status << endl;
  43. }
  44. cout << "Main: program exiting." << endl;
  45. pthread_exit(NULL);
  46. return 0;
  47. }

案例中先创建线程,然后设置线程的属性为joinable,最后回收线程,执行效果如下:

  1. main() : creating thread: 0
  2. main() : creating thread: 1
  3. main() : creating thread: 2
  4. main() : creating thread: 3
  5. main() : creating thread: 4
  6. Sleeping in thread
  7. Thread with id: 1exiting ...!
  8. Sleeping in thread
  9. Thread with id: 3exiting ...!
  10. Sleeping in thread
  11. Thread with id: 0exiting ...!
  12. Sleeping in thread
  13. Thread with id: 2exiting ...!
  14. Sleeping in thread
  15. Thread with id: 4exiting ...!
  16. Main:completed thread id:0
  17. exiting with status :0
  18. Main:completed thread id:1
  19. exiting with status :0
  20. Main:completed thread id:2
  21. exiting with status :0
  22. Main:completed thread id:3
  23. exiting with status :0
  24. Main:completed thread id:4
  25. exiting with status :0
  26. Main: program exiting.

三、移植环境搭建

大家可以注意到,上述的程序都是posix pthread接口即在Linux下使用的api,在win下默认是不能编译通过,所以编译之前我们需要做好移植工作,如下:

1.下载windows支持的posix pthread库,路径:点击打开链接

2.解压库代码:

解压pthreads-w32-2-7-0-release .rar到D盘,库路径为D:\Documents\pthreadlib\Pre-built.2\

3.在QT中指定库的路径:

LIBS += -LD:\Documents\pthreadlib\Pre-built.2\lib -lpthread

http://blog.csdn.net/xiaopangzi313/article/details/52791205

windows qt 使用c++ posix接口编写多线程程序(真神奇)good的更多相关文章

  1. 使用QtConcurrent编写多线程程序(也可以阻塞)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Amnes1a/article/details/66470751Qt在其QtConcurrent命名空 ...

  2. (转)Ubuntu下用eclipse cdt编写多线程程序的简单设置

    在Ubuntu下用eclipse cdt编写了一个多线程程序,但是总是出现pthread_create函数未定义! 查找了下原因,原来是要对eclipse进行一些简单的设置: 右键单击项目->P ...

  3. Java 中,编写多线程程序的时候你会遵循哪些最佳实践?

    这是我在写 Java 并发程序的时候遵循的一些最佳实践: a)给线程命名,这样可以帮助调试. b)最小化同步的范围,而不是将整个方法同步,只对关键部分做同步. c)如果可以,更偏向于使用 volati ...

  4. Linux多线程实践(10) --使用 C++11 编写 Linux 多线程程序

    在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程序,从 ...

  5. 使用C++编写linux多线程程序

    前言 在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程 ...

  6. [转]使用 C++11 编写 Linux 多线程程序

    前言 在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程 ...

  7. 如何提高多线程程序的cpu利用率

    正如大家所知道的那样,多核多cpu越来越普遍了,而且编写多线程程序也是件很简单的事情.在Windows下面,调用CreateThread函数一次就能够以你想要的函数地址新建一个子线程运行.然后,事情确 ...

  8. OO学习体会与阶段总结(多线程程序)

    前言 在最近一个月的面向对象编程学习中,我们进入了编写多线程程序的阶段.线程的创建.调度和信息传递,共享对象的处理,线程安全类的编写,各种有关于线程的操作在一定程度上增加了近三次作业的复杂度与难度,带 ...

  9. 在Windows下使用Dev-C++开发基于pthread.h的多线程程序【转】

    在Windows下使用Dev-C++开发基于pthread.h的多线程程序[转]     在Windows下使用Dev-C++开发基于pthread.h的多线程程序   文章分类:C++编程     ...

随机推荐

  1. oracle表空间查询维护命令大全之中的一个(数据表空间)史上最全

          表空间是数据库的逻辑划分,一个表空间仅仅能属于一个数据库. 全部的数据库对象都存放在建立指定的表空间中.但主要存放的是表, 所以称作表空间.在oracle 数据库中至少存在一个表空间.即S ...

  2. spring boot打包后在tomcat无法访问静态资源问题

    我的spring boot项目中前端页面的资源引用 我的静态文件夹是 我的application.yml中资源路径配置了 同时我在WebMvcConfig中配置了addResourceHandlers ...

  3. freemarker中间split字符串切割

    freemarker中间split字符串切割 1.简易说明 split切割:用来依据另外一个字符串的出现将原字符串切割成字符串序列 2.举例说明 <#--freemarker中的split字符串 ...

  4. 未能找到 CodeDom 提供程序类型“Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf385

    网上说的解决方案有两个,第一:什么删除目录下的.java文件,   这个方法 对我没效果:第二:删除.csproj文件中.DotNetCompilerPlatform.CSharpCodeProvid ...

  5. 【20.35%】【codeforces 651D】Image Preview

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  6. window.url.createobjecturl 兼容多种浏览器(IE,google,360,Safari,firefox)

    <script type="text/javascript"> function setImagePreview() { var docObj = document.g ...

  7. Android中自定义View和自定义动画

    Android FrameWork 层给我们提供了很多界面组件,但是在实际的商业开发中这些组件往往并不能完全满足我们的需求,这时候我们就需要自定义我们自己的视图和动画. 我们要重写系统的View就必须 ...

  8. cacti由snmp监控带宽

    1.安装和配置snmp a. yum install -y net-snmp net-snmp-utils b. chkconfig snmpd on c. chkconfig –list|grep ...

  9. HDU 4414 Finding crosses(dfs)

    Problem Description The Nazca Lines are a series of ancient geoglyphs located in the Nazca Desert in ...

  10. Lync 2013和Exchange 2013集成

    定位到下面Powershell 文件夹: C:\Program Files\Microsoft\Exchange Server\V15\Scripts\,运行例如以下命令: .\Configure-E ...