• 多线程打印


    1)题目要求

    多线程打印

    Main 线程创建两个子线程 A 和 B,子线程 A 循环 3 次,每次 sleep 一秒后打印一行十个 A 字符;

    1. int i;
    2. for (i = 0; i < 3; i++) {
    3. sleep(1);
    4. printf("AAAAAAAAAA\n");
    5. }

    子线程 B 也是循环 3 次,每次 sleep 一秒后打印一行十个 B 字符。

    多次执行程序,看看屏幕输出是什么情况。

    相关知识:

    与进程相关知识做对比,线程的api接口介绍如下:

    进程

    线程

    注释

    pid

    pthread_t

    1. 线程ID,进程ID在整个系统中是唯一的(非负整数),但线程ID不同,线程ID只在它所属的进程环境中有效
    2. pthread_t从可移植的角度来讲,其定义是一个结构,不要简单地将其看做一个整数,如果要比较,需要有专门的函数pthread_equal
    3. 如何打印pthread_t: 考虑到可移植性,这个数据结构在不同的OS上实现是不同的,所以没有一个简单的统一打印方式。(网上有一个就是直接打印结构的二进制buffer,但没有必要),如果确定在Linux上可以查看Linux的实现方式决定打印方式。

    /* Thread identifiers.  The structure of the attribute type is not exposed on purpose.  */

    typedef unsigned long int pthread_t;

    所以就Linux来说,可以直接打印%lu

    getpid

    pthread_self

    获取自身的线程ID

    fork

    int

    pthread_create(

    pthread_t *thread,

    const pthread_attr_t *attr,

    void * (* routine)(void *),

    void *arg

    )

    1. 形参:
    • thread:指向pthread_t类型的指针,该地址将存放线程创建成功之后的线程TID。
    • attr:用户设置线程的属性,一般都不需要特殊设置,所以可简单设置为NULL。
    • *(*start_routine)(void *):传递新线程所要执行的函数的地址。注意:我们可以看到,如果想启动一个线程,就必须让这个线程关联一个子函数。我们一般称此函数为线程函数,
    • arg:新线程所有执行的函数的参数,标准线程创建接口只留了 一个参数传递。思考?如果想给线程函数传递多个参数,该怎么解决呢?A:如果需要传递的参数不止一个,那么需要把参数放到一个结构里
    1. 返回值由函数直接返回,不像其他POSIX函数设置errno。

    1)线程的create涉及的入参

    2)-lpthread  

    exit

    int  pthread_exit(void *value_ptr)

    在不终止整个进程的情况下,单个线程可以有三种方式停止其工作流并退出:

    1. 线程从其工作函数中返回,返回值是线程的退出码
    2. 线程可以被同一进程中的其他线程取消
    3. 线程自己调用pthread_exit

    注意:返回value_ptr时不能将该指针指向线程工作函数内的局部变量的地址,思考?局部变量存在在栈上,线程函数退出后,这个局部变量无效了,有可能在join时得到的会是无效值。所以如果要传一个结构,最好定义在堆上或者使用全局变量。

    void *workfunc(void *arg) {

     int local = 0;

     pthread_exit(&local); // danger!

    }

    waitpid

    int  pthread_join(pthread_t thread,  void **value_ptr)

    一般此函数用在主线程中,等待通过thread指定的线程终止,此函数调用成功,可以通过value_ptr获取终止线程的返回值。

    注意:如果等待的线程没有终止,此函数将引起调用者阻塞。成功返回0,失败返回-1。

    线程执行完后如果不join的话,线程的资源会一直得不到释放而导致内存泄漏!所以需要join或者detach,本课程不讲detach,有兴趣学生自己回去看

    abort

    int  pthread_cancel(pthread_t thead)

    线程通过调用pthread_cancel来请求取消同一个进程中的其他线程。pthread_cancel并不等待线程终止,仅提出请求。

    审核要求:

    1. 提交全部程序代码,代码思路规范清晰,命名规范。

    2. 运行能直接输出所要求的结果。

    2)实现过程

    1. #include
    2. #include
    3. void *funa(void *arg)
    4. {
    5. int i;
    6. for(i=0;i<3;i++){
    7. sleep(1);
    8. printf("AAAAAAAAAA\n");
    9. }
    10. pthread_exit(NULL);
    11. }
    12. void *funb(void *arg)
    13. {
    14. int i;
    15. for(i=0;i<3;i++){
    16. sleep(1);
    17. printf("BBBBBBBBBB\n");
    18. }
    19. pthread_exit(NULL);
    20. }
    21. int main()
    22. {
    23. pthread_t ta,tb;
    24. if(0!=pthread_create(&ta,NULL,funa,NULL))
    25. {
    26. perror("pthread error!");
    27. exit(0);
    28. }
    29. if(0!=pthread_create(&tb,NULL,funb,NULL))
    30. {
    31. perror("pthread error!");
    32. exit(0);
    33. }
    34. if(0!=pthread_join(ta,NULL))
    35. {
    36. perror("join error\n");
    37. exit(0);
    38. }
    39. if(0!=pthread_join(tb,NULL))
    40. {
    41. perror("join error\n");
    42. exit(0);
    43. }
    44. return 0;
    45. }

  • 相关阅读:
    【图解计算机网络】网络协议分层解析
    如何在迅睿CMS中使用if语句判断多个栏目ID
    API接口自动化测试
    使用 Pycharm 调试远程代码
    sort方法实现复杂排序
    【LeetCode刷题-滑动窗口】--1695.删除子数组的最大得分
    Docker网络通信原理
    huatuo 革命性热更新解决方案系列1·1 为什么这么NB?huatuo革命Unity热更新
    【PAT甲级 - C++题解】1068 Find More Coins
    自动化测试执行过程和报告内容分析
  • 原文地址:https://blog.csdn.net/L6666688888/article/details/128075516