• c++ 线程学习笔记


    线程创建函数:pthread_create(thread,attr,start_routine,arg)

    这个函数在pthread.h中,它的四个参数分别表示:

    thread:  指向线程标识符的指针,传入时一般都用&thread[i]这样的写法(一般是多个线程,所以用线程数组)

    attr:  线程参数,一般可以填成NULL

    start_routine:  要运行函数的首地址,按照C的特性,传入函数指针即可

    arg:  要运行函数的参数,如果没有参数,可以填成NULL   如果要使用,必须使用指针,并且必须是void指针。比如传入时写(void*)&(num[i])

    该线程有返回值,返回值为0表示创建线程成功,反之失败。

     -------------------------------------------------------------------------------

    linnux中,线程退出有三种方式:执行完内容后自己退出;被同进程中的其他线程强行终止,或者通过pthread_exit()函数主动退出

    线程中止函数:pthread_exit(void* retval)

    可以使线程主动退出,它的参数是一个void指针,可以指向任何数据,但是不能将其指向局部变量,因为函数结束以后就没了嘛。类似于普通函数的返回值,如果没有要传递的值则为NULL。

    注意:在使用此函数退出线程时,由于线程间共享资源,退出的线程资源不会被释放,如果需要可以用pthread_join来处理。

    此时存在了一个问题:主线程中的结束一般用的都是return 0,但用多线程时应该使用pthread_exit()函数,因为return结束的话,如果主线程运行太快先结束,那其他子线程也要被迫结束掉

    。所以需要换成pthread_exit(),这样就不会影响到其他线程运行(主线程资源已经释放,但没有退出)。子线程的退出也可以用pthread_exit()函数。

    #include <iostream>
    // 必须的头文件
    #include <pthread.h>
     
    using namespace std;
     
    #define NUM_THREADS 5
     
    // 线程的运行函数
    void* say_hello(void* args)
    {
        cout << "This is a test" << endl;
        return 0;
    }
     
    int main()
    {
        // 用pthread_t定义线程的 id 变量,多个变量使用数组
        pthread_t tids[NUM_THREADS];
        for(int i = 0; i < NUM_THREADS; ++i)
        {
            //参数依次是:创建的线程id,线程参数,调用的函数,传入的函数参数
            int ret = pthread_create(&tids[i], NULL, say_hello, NULL);
            if (ret != 0)
            {
               cout << "pthread_create error: error_code=" << ret << endl;
            }
        }
        //如果这里用return,主线程结束时子线程没运行完就会被强制结束;
        pthread_exit(NULL);
    }

    因为exit()会调用线程清理功能,所以子线程最好使用pthread_exit()来结束,主线程根据需要,看情况用pthread_exit()或者return。

     ----------------------

    线程连接和分离:

    pthread_join(threadid,*retval)

    pthread_detach(threadid)

    在某些时候,主线程创建子线程时,子线程承担了大量计算任务,运行比主线程慢,但是主线程又需要用到子线程的计算结果,就需要主线程等待子线程。

    线程在创建时会有一个属性,定义其是可连接(join)的还是分离(detach)的,可连接的话,该线程可以使用join函数连接,否则永远不能被连接。连接意味着一旦在主线程中调用该函数,则主线程会一直阻塞着,直到子线程运行完成。

    jon()函数   : 包含两个参数,threadid是要连接的线程号,retval是指向子线程返回值的指针

    在创建子线程后使用。主线程中使用join后,主线程就会阻塞,直到子线程结束。当join()函数返回后,被调用的线程才会真正结束。

    返回值为0表示连接成功 其他均为失败

    (注意:join只会清理系统清理的内存,malloc申请的空间仍需要手动释放,并且一个线程只能被一个线程连接)

    初始将线程属性设置为可连接的方式:

     #include <pthread.h> 
    
    pthread_t threads[NUM_THREADS];
    pthread_attr_t attr;
    
    // 初始化并设置线程为可连接的(joinable)
       pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    ----------------------

    注意:linux原生不带pthread库,如果要用,编译时指令要在 后面加上-pthread

    例:g++ test.cpp -pthread  -o test.o

  • 相关阅读:
    安装Hadoop
    爬虫综合大作业
    理解爬虫原理
    中文词频统计与词云生成
    复合数据类型,英文词频统计
    字符串操作、文件操作,英文词频统计预处理
    了解大数据的特点、来源与数据呈现方式
    结对项目-四则运算 “软件”之升级版
    分布式版本控制系统Git的安装与使用
    Maven 依赖的scope标签用法
  • 原文地址:https://www.cnblogs.com/namezhyp/p/16183053.html
Copyright © 2020-2023  润新知