• 多线程入门


    1 创建线程

    下面的程序,我们可以用它来创建一个 POSIX 线程:

    1. #include
    2. pthread_create (myThread, attr, start_routine, arg)

    在这里,pthread_create 创建一个新的线程,并让它可执行。下面是关于参数的说明: 

    参数描述
    myThread指向线程标识符指针
    attr一个不透明的属性对象,可以被用来设置线程属性。您可以指定线程属性对象,也可以使用默认值 NULL。一般不需要关注,直接用NULL即可。
    start_routine线程运行函数起始地址,一旦线程被创建就会执行。函数内部就是子线程要运行的内容。
    arg运行函数的参数。必须通过把引用作为指针强制转换为 void 类型进行传递。如果没有传递参数,则使用 NULL。一般不需要关注,直接用NULL即可。

    2 终止线程

    终止线程可采用return NUL自动退出,也可以采用pthread_exit(NULL)强制退出。

    3 示例

    3.1 示例代码

    该代码先执行main函数,然后创建了一个子线程thread_func,此时就存在两个线程,一个主线程,一个子线程。主线程运行一个计算(for循环i);子线程运行一个计算(for循环j)。最后主线程计算结束,子线程计算结束,子线程退出,主线程退出。整个程序结束。

    1. #include <pthread.h>
    2. #include <unistd.h>
    3. #include <stdio.h>
    4. void *thread_func(void *arg)
    5. {
    6. while (1)
    7. {
    8. for (int j = 0; j < 8; j++)
    9. {
    10. printf("sub:%d\n", j);
    11. usleep(10);
    12. }
    13. if(true/*线程不在使用了,可以退出*/){
    14. break;
    15. }else{
    16. //子线程后面还要使用
    17. usleep(10*1000);
    18. continue;//进入下个循环
    19. }
    20. }
    21. printf("sub thread return\n");
    22. return NULL;
    23. }
    24. int main()
    25. {
    26. pthread_t tid;
    27. pthread_create(&tid, NULL, thread_func, NULL);
    28. for (int i = 0; i < 8; i++)
    29. {
    30. printf("main:%d\n", i);
    31. usleep(10);
    32. }
    33. pthread_join(tid, NULL);
    34. printf("main thread: all threads exit.\n");
    35. return 0;
    36. }

    3.2 编译

    编译脚本为gcc Demo1.cpp -o Demo1 -lpthread。会生成名字为Demo的可执行程序。

    Demo1.cpp中有使用线程技术,需要链接pthread库,即在编译脚本中添加-lpthread。

    3.3 运行

    ./Demo1就是运行。运行逻辑示意图如下。

    (1)主线程逻辑图:

    (2)子线程逻辑图:

     (3)CPU内核使用情况

    总结: 如果只有一个主线程,则只能使用一个主线程内核,所以对于耗时较大的任务,使用多线程可以提高性能。 

    3.4 结果分析

    可以看到结果,主线程main计算和子线程sub计算同时运行,节省了时间。

    下面我们打印时间,进行对比。

    (1)代码示例:

     (2)编译运行结果

    由此可见,使用一个子线程和一个主线程来进行2个计算,耗时较短,这是因为两个子线程分别持有一个CPU内核,并行进行计算。 缩短了总共时间

    另外创建线程也会耗时,如果计算耗时小于创建线程的耗时,则2个线程总共耗时不会优于一个线程,即总共耗时:创建线程耗时+计算1耗时+计算2耗时....。

    3.5 源代码

    3.3中统计时间的源代码。

    Demo1.cpp

    1. #include <pthread.h>
    2. #include <unistd.h>
    3. #include <stdio.h>
    4. #include <sys/time.h>
    5. #include <unistd.h>
    6. #include <stdio.h>
    7. struct timeval time1, time2;
    8. void *thread_func(void *arg)
    9. {
    10. // 执行一些操作...
    11. int totalSub = 0;
    12. for (int j = 0; j < 80; j++)
    13. {
    14. int jk = ((j << 2) * 8) >> 2;
    15. int jl = ((j << 4) * 8) >> 4;
    16. totalSub = totalSub + jk + jl; // 计算1
    17. usleep(10 * 1000);
    18. }
    19. printf("sub total:%d\n", totalSub);
    20. printf("sub thread return\n");
    21. return NULL;
    22. }
    23. int main()
    24. {
    25. double elapsed_time = 0.0;
    26. gettimeofday(&time1, NULL);
    27. pthread_t tid;
    28. pthread_create(&tid, NULL, thread_func, NULL);
    29. int totalmain = 0;
    30. for (int i = 0; i < 10; i++)
    31. {
    32. int ik = ((i << 2) * 8) >> 2;
    33. int il = ((i << 4) * 8) >> 4;
    34. totalmain = totalmain + il; // 计算2
    35. usleep(10 * 1000);
    36. }
    37. printf("main total:%d\n", totalmain);
    38. pthread_join(tid, NULL);
    39. gettimeofday(&time2, NULL);
    40. elapsed_time = (time2.tv_sec - time1.tv_sec) * 1000 + (time2.tv_usec - time1.tv_usec) / 1000;
    41. printf("Elapsed time: %lf(ms)\n", elapsed_time);
    42. printf("main thread: all threads exit.\n");
    43. return 0;
    44. }

     Demo2.cpp 

    1. #include <pthread.h>
    2. #include <unistd.h>
    3. #include <stdio.h>
    4. #include <sys/time.h>
    5. #include <unistd.h>
    6. #include <stdio.h>
    7. struct timeval time1, time2;
    8. int main()
    9. {
    10. double elapsed_time = 0.0;
    11. gettimeofday(&time1, NULL);
    12. int totalSub = 0;
    13. int totalmain = 0;
    14. for (int j = 0; j < 80; j++)
    15. {
    16. int jk = ((j << 2) * 8) >> 2;
    17. int jl = ((j << 4) * 8) >> 4;
    18. totalSub = totalSub + jk + jl; // 计算1
    19. usleep(10*1000);
    20. }
    21. printf("main total:%d\n", totalSub);
    22. for (int i = 0; i < 10; i++)
    23. {
    24. int ik = ((i << 2) * 8) >> 2;
    25. int il = ((i << 4) * 8) >> 4;
    26. totalmain = totalmain + il; // 计算2
    27. usleep(10*1000);
    28. }
    29. printf("sub total:%d\n", totalSub);
    30. gettimeofday(&time2, NULL);
    31. elapsed_time = (time2.tv_sec - time1.tv_sec) * 1000 + (time2.tv_usec - time1.tv_usec)/1000;
    32. printf("Elapsed time: %lf(ms)\n", elapsed_time);
    33. return 0;
    34. }

  • 相关阅读:
    Jetpack:008-Icon与Image
    认识单链表
    [Codeforces] number theory (R1200) Part.7
    【路径规划-TSP问题】基于粒子群结合蚁群算法求解旅行商问题附matlab代码
    go的编译以及运行时环境
    JAVA堆中的对象结构
    【C语言】字符串左旋(三种方法)
    微信小程序 自定义tab不煽动
    前后端接口设计与配置中心系统<二十九>-------HiAbility SDK开发3【 扫码能力集成、数据统计与埋点】
    【项目实战】自主实现 HTTP 项目(一)——tcp、http的创建与实现较兼容的行读取
  • 原文地址:https://blog.csdn.net/qq_34754747/article/details/133786977