Linux下多线程简单使用



  • pthread_create是类Unix操作系统的创建线程的函数。它通过参数中传入的运行函数指针和运行函数的参数来执行相应的线程,线程id由第一个参数的指针指向。返回值:0表示成功,-1表示出错
    pthread_join以阻塞的方式等待指定线程id的线程结束,该线程的返回值存放在第二个参数中。当函数返回时,被等待线程的资源被回收

    两函数的原型如下:
    int pthread_create(pthread_t *restrict tidp,const pthread_attr_t restrict_attr,voidstart_rtn)(void),void *restrict arg);
    第一个参数为指向线程标识符的指针
    第二个参数用来设置线程属性
    第三个参数是线程运行函数的地址
    第四个参数是运行函数的参数

    int pthread_join(pthread_t __th, void **__thread_return);
    第一个参数是线程id
    第二个参数是用来存储被等待线程的返回值



  • emmm,我认真看了,嗯,不懂。



  • 就是可以用pthread_create创建线程,这个函数的参数中传入线程的id以及你想执行的函数,之后用pthread_join获取这个线程的返回值。



  • 能配合例子就更好了👀



  • pthread_create函数是创建一个新的线程,新创建的线程会调用一个函数。
    可以看一下下面的简单例子, 分别两次用pthread_create创建了两个线程,分别调用了打印信息的功能,在message中传入了字符串并有printer_function打印到屏幕上,(但是下面的做法是很危险的,后面会说),先可以看一下代码。

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    void *printer_function(void *message) {
        printf("Printer begin functioning! Message: %s!\n", (char *)message);
        return NULL;
    }
    
    int main(void) {
        pthread_t printer1, printer2;
        int iret1, iret2;
        
        if ((iret1 = pthread_create(&printer1, NULL, printer_function, "hello")) != 0) {
            // error creating the first thread
            perror("Create thread for printer1 failed!\n");
            exit(1);
        }
    
        if ((iret2 = pthread_create(&printer2, NULL, printer_function, "bello")) != 0) {
            // error creating the second thread
            perror("Create thread for printer2 failed!\n");
            exit(1);
        }
        
        /* Wait till threads are complete before main continues */
        pthread_join(printer1, NULL);
        pthread_join(printer2, NULL);
    }
    

    这里pthread_join是等待printer1printer2结束之后再结束主线程。如果子线程是一个无限循环,不使用pthread_join则可能会发生主线程结束,但是子线程没有结束,也无法回收资源的情况。

    最后再强调一下,由于子线程之间共享当前进程的变量,且由于操作系统分时处理线程。所以上面的代码存在着输出混乱的可能(有可能printer1输出了一半之后,printer2接着输出),所以一般在使用子线程时常常需要配合信号灯semaphore或者锁lock(常用互斥锁mutex)来控制公共变量的访问。

    上面是我自己写的代码,编译的时候需要link pthread库,建议自己加一下mutex体会一下

    gcc foo.c -lpthread
    

    如果有问题可以再问


  • 核心层

    @vinstarry 记得叫他们请你吃饭



  • @liangfs hahaha~


  • 项目组组长

    最近正在做课设,认真看了



  • @ZhangXin 网上也有一些例子,可以看看



  • @vinstarry 分多线程进行数字累加的问题我觉得等长分段效率并不好,但不知道有没有效率更高的做法。



  • @jaychou 你指的是对一个数组进行累加,然后等长分段,每个段用一个线程处理吗
    在数据量很大的情况下,我认为等长的效果应该不会太差。



  • 这,叫“使用”,不是“实现”



  • @wqy 已改👀



  • @vinstarry 总结的非常不错



  • @vinstarry 我的意思是说可不可以充分利用时间,因为在等长分段时候,往往是一个线程结束了,另一个还在跑,如果这个时候,能让快结束的线程继续工作的话,效率就更高了。我不知道这个该怎么做。



  • @jaychou 我觉得可能数据量还是不够大?如果线程平等的话应该差距不太大的,具体上我也不是太懂,体系结构还没学,建议你请教一下老师。


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

Looks like your connection to Dian was lost, please wait while we try to reconnect.