windows qt 使用c++ posix接口编写多线程程序(真神奇)good

摘要:
基于线程的多任务是同时执行同一程序的片段。多线程程序包含两个或多个可以同时运行的部分。这种程序的每个部分都称为线程。每个线程定义一个单独的执行路径。C++不包含对多线程应用程序的任何内置支持。执行效果:[cpp]viewplatecopymain():创建线程,0main():新建线程,1HelloRunoob!线程ID,2main():创建线程,4HeloRunoob!相反,一个单独的线程不能被其他线程回收或终止。当它终止时,系统会自动释放它的内存资源。线程的分离状态决定了线程如何终止自己。

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

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

1. 多线程实现

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

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

执行效果:

[cpp] view plain copy
 
  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线程属性,让线程以分离状态启动.

代码如下:

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

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

[cpp] view plain copy
 
  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:DocumentspthreadlibPre-built.2

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

LIBS += -LD:DocumentspthreadlibPre-built.2lib -lpthread

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

免责声明:文章转载自《windows qt 使用c++ posix接口编写多线程程序(真神奇)good》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mac 命令行安装软件VC add files to folder失效问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Web Worker javascript多线程编程(一)

什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验。 一般来说Javascript和UI页面会共用一个线程,在HTML页面中执行js脚本时,页面的状态是不可响应的,直到脚本已完成。而这段代码可以交给Web Worker在后台运行,那么页面在...

正确使用Android性能分析工具——TraceView

TraceView界面 现来看一下整个界面的图,整个界面包括上下两部分,上面是你测试的进程中每个线程的执行情况,每个线程占一行;下面是每个方法执行的各个指标的值 上面一部分是你测试进程的中每个线程运行的时间线,下图中可以可以看到,主要只有一个main线程在执行,因为我滑动了一下列表,main线程(UI线程)正在进行绘制View呢~~ 然后我点击了序号为13...

C# 当前程序所有线程

using System.Linq; var threads = System.Diagnostics.Process.GetCurrentProcess().Threads;var count = threads.Count;var actived = threads.Cast<ProcessThread>().Where(t => t...

记一个多线程使用libevent的问题

前段时间使用libevent网络库实现了一个游戏服务器引擎,在此记录下其中遇到的一个问题。 我在设计服务器上选择把逻辑和网络分线程,线程之间通信使用队列。但是这样做会有个问题: 当逻辑线程想要主动的发一个数据包的时候,网络线程此时可能还阻塞在等待网络IO的系统调用上(比如说epoll)。如果不做特殊处理的话,此时消息包就会一直积压在缓冲区中,直到下一次网络...

[转]高性能网络编程中的线程模型

转自 https://mp.weixin.qq.com/s/jDeA4zayOnF0GxgRci7oaA 在文章“一文读懂高性能网络编程中的I/O模型”中,介绍了服务器如何基于 I/O 模型管理连接,获取输入数据,下面将介绍基于进程/线程模型,服务器如何处理请求。 值得说明的是,具体选择线程还是进程,更多是与平台及编程语言相关。 例如 C 语言使用线程和进...

http协议多线程文件传输

      HTTP亦即Hpyer Text Transfer Protocal的缩写,它是现代互联网上最重要的一种网络协议,超文本传输协议位于TCP/IP协议的应用层,是一个面向无连接、简单、快速的C/S结构的协议。HTTP的工作过程大体上分连接、请求、响应和断开连接四个步骤。C#语言对HTTP协议提供了良好的支持,在.NET类库中提供了WebReque...