9、操作系统——线程的相关属性(1)(线程分离和结合)

目录

一、线程相关属性的API

1、线程的特殊属性

2、设置线程的属性

3、注意事项

二、线程属性变量的使用步骤

三、相关的API

1、pthread_attr_init/pthread_attr_destroy(初始化、销毁线程属性变量)

2、pthread_attr_setdetachstate、pthread_attr_getdetachstate(获取、设置线程的分离属性)

3、使僵尸进程被系统回收,获取其退出的值的API

(1) pthread_exit(退出线程)

(2)pthread_join、pthread_tryjoin_np(接合指定线程)

四、结合属性代码

五、分离属性的线程结合

一、线程相关属性的API

1、线程的特殊属性

2、设置线程的属性

3、注意事项

  • 上述的API都是针对线程属性操作,线程属性是类型为 pthread_attr_t 的变量
  • 设置一个线程的属性时,通过以上的函数接口,将需要的属性添加到该类型变量里面,再通过pthread_create( )的第二个参数来创建相应属性的线程
  • 设置线程的属性必须要在创建先成功之前

二、线程属性变量的使用步骤

a、定义线程属性变量,并且使用 pthread_attr_init( )初始化。

b、使用 pthread_attr_setXXX( )来设置相关的属性。

c、使用该线程属性变量创建相应的线程。

d、使用 pthread_attr_destroy( )销毁该线程属性变量。

三、相关的API

1、pthread_attr_init/pthread_attr_destroy(初始化、销毁线程属性变量)

2、pthread_attr_setdetachstate、pthread_attr_getdetachstate(获取、设置线程的分离属性)

注意

(1)线程缺省的情况下是接合的

(2)线程若是接合的,意味着线程在退出时不会自动释放自身资源,会成为僵尸进程,则 该线程的推出值可以被其他线程获取。

(3)如果不需要某线程的退出值,则将线程设置为分离状态,保证线程不会成为僵尸进程

3、使僵尸进程被系统回收,获取其退出的值的API

缺省状态下退出后,会成为僵尸进程,并且保留退出值

其他线程可以通过pthread_exit使其资源被系统回收,还可以获取退出的值

(1) pthread_exit(退出线程)

缺省状态下退出后,会成为僵尸进程,并且保留退出值

其他线程可以通过pthread_exit使其资源被系统回收,还可以获取退出的值

(2)pthread_join、pthread_tryjoin_np(接合指定线程)

注意:
(1)如果线程退出时没有退出值,那么 retval 可以指定为 NULL。

(2)pthread_join( )指定的线程如果尚在运行,那么他将会阻塞等待。

(3)pthread_tryjoin_np( )指定的线程如果尚在运行,那么他将会立即出错返回。

四、结合属性代码

#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>

void * func (void * arg)
{
    while(1)
    {
        printf("这里是func线程,线程ID :%ld \n" , pthread_self() );
        sleep(3);
        break ;
    }

    int * p = calloc(1,4);
    *p = 1024444 ;
    // 退出本线程并设置返回值的地址(返回了num 的地址)
    pthread_exit((void *)p); //返回的内存地址应该时一个堆空间
}

int main(int argc, char const *argv[])
{
    
    // 创建线程
    pthread_t t_id  = -1 ;
        
    pthread_create( &t_id , //新线程ID号
                    NULL , // 线程属性, NULL 默认属性
                    func,  // 线程需要执行的例程(新线程需要执行的任务《函数》) 
                    NULL ); // 线程的参数

    printf("t_id : %ld\n" , t_id) ;

    printf("这里是主函数,线程ID :%ld \n" , pthread_self() );

    int * retval ;
    // 阻塞等待接合线程
    printf("等待 function 线程退出:\n");
    pthread_join( t_id , (void*)&retval);
    printf("结合线程成功, 退出值为:%d\n" , *retval);

    // 尝试接合线程  (非阻塞)
    // int ret_val = 0 ;
    // if( ret_val = pthread_tryjoin_np( t_id , (void*)&retval))
    // {
    //     fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
    // }

    return 0;
}

若线程退出,则退出值为*p的值

五、分离属性的线程结合

#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>

void * func (void * arg)
{
    while(1)
    {
        printf("这里是func线程,线程ID :%ld \n" , pthread_self() );
        sleep(3);
        break ;
    }

    int * p = calloc(1,4);
    *p = 1024444 ;
    // 退出本线程并设置返回值的地址(返回了num 的地址)
    pthread_exit((void *)p); //返回的内存地址应该时一个堆空间
}

int main(int argc, char const *argv[])
{

    // 创建线程属性变量
    pthread_attr_t attr ;
    // 初始化线程属性
    pthread_attr_init(&attr);
    // 设置属性信息 (分离属性)
    if(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED))
    {
        printf("设置分离属性失败!!\n");
    }
    else{
        printf("设置分离属性成功!!\n");
    }

    
    // 创建线程
    pthread_t t_id  = -1 ;
        
    pthread_create( &t_id , //新线程ID号
                    &attr , // 线程属性(当前设置为分离)
                    func,  // 线程需要执行的例程(新线程需要执行的任务《函数》) 
                    NULL ); // 线程的参数

    printf("t_id : %ld\n" , t_id) ;

    printf("这里是主函数,线程ID :%ld \n" , pthread_self() );

    int * retval ;
    int ret_val = 0 ;
    // 阻塞等待接合线程
    printf("等待 function 线程退出:\n");
    if(ret_val = pthread_join( t_id , (void*)&retval))
    {
        fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
        return -1 ;
    }
    printf("结合线程成功, 退出值为:%d\n" , *retval);

    // 尝试接合线程  (非阻塞)
    // int ret_val = 0 ;
    // if( ret_val = pthread_tryjoin_np( t_id , (void*)&retval))
    // {
    //     fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
    // }

    return 0;
}

输出:结合失败:Invalid atgument

设置为分离属性了,不可以结合

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值