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


    一、多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。一般情况下,两种类型的多任务处理:基于进程和基于线程。基于进程的多任务处理是程序的并发执行。基于线程的多任务处理是同一程序的片段的并发执行。多线程程序包含可以同时运行的两个或多个部分。这样的程序中的每个部分称为一个线程,每个线程定义了一个单独的执行路径,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. }  

    上述案例使用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

  • 相关阅读:
    Codeforces 627A XOR Equation(思路)
    Codeforces 633C Spy Syndrome 2(DP + Trie树)
    BZOJ 1982 [Spoj 2021]Moving Pebbles(博弈论)
    BZOJ 3676 [Apio2014]回文串(回文树)
    BZOJ 3790 神奇项链(manacher+DP+树状数组)
    Codeforces 449D Jzzhu and Numbers(高维前缀和)
    SPOJ Time Limit Exceeded(高维前缀和)
    BZOJ 4031 [HEOI2015]小Z的房间(Matrix-Tree定理)
    BZOJ 3809 Gty的二逼妹子序列(莫队+分块)
    BZOJ 3544 [ONTAK2010]Creative Accounting(set)
  • 原文地址:https://www.cnblogs.com/findumars/p/6375665.html
Copyright © 2020-2023  润新知