• 6、程序、进程、线程(二)


    linux下的线程

    与传统的进程相比,用线程来实现相同的功能有如下优点:

    1. 系统资源消耗低
    2. 速度快
    3. 线程间的数据共享比进程间容易的多

    编写linux下的线程需要包含头文件pthread.h

    一个简单的多线程例子:

    #include
    #include
    #include
    
    static int run = 1;//运行状态参数
    static int retvalue;//线程返回值
    
    void *start_routine(void *arg) { //线程处理函数
        int *running = arg;
        printf("子线程初始化完毕, 传入参数为 %d\n",*running);
    
        while(*running) {
            printf("子线程正在运行\n");
            usleep(1);
        }
        printf("子线程退出\n");
    
        retvalue = 8;
        pthread_exit((void*)&retvalue);
    }
    
    int main(int argc, char *argv[]) {
        pthread_t pt;
        int ret = -1;
        int times = 3;
        int i = 0;
        int *ret_join = NULL;
    
        ret = pthread_create(&pt, NULL, (void*)start_routine, &run);//建立线程
    
        if(ret != 0 ) {
            puts("建立线程失败");
            return 1;
        }
        usleep(1);
    
        for(;i<times;i++) {
            puts("主线程打印");
            usleep(1);
        }
        run = 0; //设置线程控制值,让线程退出
        pthread_join(pt, (void*)&ret_join);
        printf("线程返回值为 :%d\n",*ret_join);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    编译的时候记得要指定线程库gcc pthread.c -lpthread -o pthread

    linux下的线程创建函数 pthread_create
    #include 
    
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
     void *(*start_routine) (void *), void *arg);
    
    //Compile and link with -pthread.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第一个参数是线程标识符,第二个参数用于设置线程的属性,为NULL时采用默认属性。第三个参数是一个返回值为void*,参数为void*的函数,是线程分配完资源后要执行的部分。线程函数运行时传入的参数,也就是第三个参数的函数需要传入的参数。

    当线程创建成功时返回 0 ,否则表示失败了。常见的错误代码有EAGAIN、EINVAL,EAGAIN表示系统中的线程达到了上线,EINVAL表示线程的属性非法。线程创建成功后新创建的先按照参数3和4执行,原来的线程在线程创建函数返回后继续执行下一行代码。

    线程的结束函数pthread_join、pthread_exit

    函数pthread_join用来等待一个线程运行结束,这个函数是阻塞函数

    #include 
    
    int pthread_join(pthread_t thread, void **retval);
    
    //Compile and link with -pthread.
    
    • 1
    • 2
    • 3
    • 4
    • 5

    第一个参数是线程标识符,第二个参数是线程结束后返回的值。

    线程函数(上述为start_routine)的结束方式有两种,一种是线程函数运行结束,不用返回结果,另一种是通过线程函数pthread_exit函数结束,函数的参数为 被捕获的返回值。

    #include 
    
    void pthread_exit(void *retval);
    
    //Compile and link with -pthread.
    
    • 1
    • 2
    • 3
    • 4
    • 5

    线程的属性

    在上面用pthread_create创建函数的时候,使用了默认参数,即将第二个参数设为NULL,通常来说建立一个线程时使用默认属性就行了,但是很多时候需要调整线程的属性,特别是线程的优先级。

    线程的属性结构

    pthread_attr_t

    
    
    • 1

    线程属性的初始化函数是pthread_attr_init,这个函数必须在pthread_create之前调用。属性对象主要包括 线程的摘取状态、调度优先级、运行栈地址、运行栈大小、优先级。

    #include 
    
    int pthread_attr_init(pthread_attr_t *attr);
    int pthread_attr_destroy(pthread_attr_t *attr);
    
    //Compile and link with -pthread.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    线程优先级

    线程优先级是经常设置的属性,由两个函数进行控制,pthread_attr_getschedparam获得线程的优先级设置;函数pthread_attr_setschedparam设置线程的优先级。

    #include 
    
    int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);
    int pthread_attr_getschedparam(const pthread_attr_t *attr,struct sched_param *param);
    
    Compile and link with -pthread.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    线程的优先级存放在结构sched_param中,其操作方式是先将优先级取出来,设置完后再放回去,

    互斥锁与信号量

  • 相关阅读:
    软件系统测试有什么注意事项?对软件产品起到什么作用?
    Python牛客刷题笔记
    安卓玩机搞机技巧综合资源------如何提取手机分区 小米机型代码分享等等 【一】
    prometheus学习
    白酒:茅台镇白酒的文化内涵与传承意义
    C++QT实现TCP通信
    WebSocket 和 Socket 的区别
    单克隆抗体WuT9/甘草次酸-氟尿嘧啶偶联顺铂/RGD肽修饰聚谷氨酸-顺铂复合物的制备
    因误删文件导致CentOS7开机卡死无法进入图形登录界面
    JCMSuite应用-高功率半导体激光器
  • 原文地址:https://blog.csdn.net/m0_45972156/article/details/126452501