栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

线程学习笔记总结

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程学习笔记总结

文章目录
  • 进程概述
  • 线程创建
  • 线程退出
    • pthread_exit函数
    • pthread_cancel函数
    • pthread_join函数(回收线程)
  • 线程分离pthread_detach
  • 线程属性

进程概述

进程:有独立的进程地址空间,有独立的PCB
线程:没有独立的地址空间,是共享的,有独立的PCB
Linux下,线程是最小的执行单位,进程是最小的分配资源的单位

LWP: 轻量级进程也就是线程
命令
ps -Lf pid
可以查看该进程的线程号

线程创建
      int pthread_create(pthread_t *thread,       //传出参数,表示创建的线程的线程id 
                         const pthread_attr_t *attr, //表示线程属性,传NULL表示使用默认属性
                         void *(*start_routine) (void *),//回调函数,会自动调用
                         void *arg);                  //上一个参数的参数

返回值:成功返回0
失败返回perror

#include
#include
#include
#include
void* tfn(void*arg)
{
    printf("phread:pid = %d,tid = %lun",getpid(),pthread_self());
}
int main()
{
    pthread_t tid;
    printf("mian : pid = %d ,tid = %lun",getpid(),pthread_self());
    int ret=pthread_create(&tid,NULL,tfn,NULL);
    if(ret!=0)
    {
        perror("pthread");
    }
    sleep(1);
    return 0;
}
线程退出 pthread_exit函数
       void pthread_exit(void *retval);

参数是传出参数,此函数的作用是终止一个调用他的线程
eg:循环创建五个子线程,终止第三个子线程

#include
#include
#include
#include
#include
void func()
{
      pthread_exit(NULL);
}
void*tfn(void*argv)
{
    int i=(int)argv;
    sleep(i);
    if(i==2)//第三个线程退出
    {
       // exit(1);//表示退出进程
       //return NULL;//表示返回到函数调用者那里
       func();
      
    }
    printf("I am %d ,pthread: pid = % d,tid = %lun",i+1,getpid(),pthread_self());
}
int main()
{
    int i=0;
    int ret;
    pthread_t tid;
    for(i=0;i<5;i++)
    {
        ret=pthread_create(&tid,NULL,tfn,(void*)i);
        if(ret!=0)
        {
            perror("pthread_create");
            exit(1);
        }
    }
    //sleep(i);
    printf("i am mainn");
    //return 0;
    pthread_exit(NULL);
}

执行结果:

pthread_cancel函数
 int pthread_cancel(pthread_t thread);

回收特定线程,传入参数是要终止的线程id
为了看到效果,用一个死循环代码来展示效果

#include
#include
#include
#include
#include
#include
void*tnf(void*arg)
{   while(1)
  {
    printf(" thread: pid = %d,tid = %lun",getpid(),pthread_self());
    sleep(1); 
  }
}
int main()
{
    pthread_t tid;
    int ret =pthread_create(&tid,NULL,tnf,NULL);
    if(ret<0)
    {
        perror("create");
        exit(1);
    }
    sleep(3);
    ret=pthread_cancel(tid);
    while(1);
    return 0;
}

效果:

pthread_join函数(回收线程)

阻塞等待线程退出,并且获得线程退出状态(返回值),很类似于进程中的waitpid函数

int pthread_join(pthread_t thread, void **retval);

参数:
thread 要堵塞等待退出的线程id
retval 退出状态
eg:

#include
#include
#include
#include
#include
#include
typedef struct pdf
{
    int var;
    char arr[100];
}pdf;
void*tnf(void*arg)
{
    struct pdf* p1;
    p1=(pdf*)malloc(sizeof(pdf));
    p1->var=100;
    strcpy(p1->arr,"hello world");
    return (void*)p1;
}
int main()
{
    pthread_t tid;
    pdf* p1;
    int ret =pthread_create(&tid,NULL,tnf,NULL);
    pthread_join(tid,(void**)&p1);
    printf("tar=%d,arr=%sn",p1->var,p1->arr);
    return 0;
}

结果:

线程分离pthread_detach

线程分离状态:指定该状态,线程主动与主控线程断开关系。线程结束后,其退出状态不由其它线程获取,而直接自己自动释放

 int pthread_detach(pthread_t thread);

参数:所要分离的线程

#include
#include
#include
#include
#include
#include
void*tfn(void*arg)
{
    printf("thread : pid = %d, tid = %lun",getpid(),pthread_self());
    return NULL;
}
int main()
{
    pthread_t tid;
    int ret=pthread_create(&tid,NULL,tfn,NULL);
    if(ret!=0)
    {
        perror("create error");
        exit(1);
    }
    sleep(2);
    ret=pthread_detach(tid);
    if(ret!=0)
    {
        fprintf(stderr,"pthread_deach error:%sn",strerror(ret));
        exit(1);
    }
    ret=pthread_join(tid,NULL);
    if(ret!=0)
    {
        fprintf(stderr,"pthread_join error:%sn",strerror(ret));
        exit(1);
    }
    return 0;
}

结果:

当我们对线程分离后,再当我们使用线程退出函数就会报无效参数的错误

线程属性

属性值不能直接设置,须使用相关函数进行操作,初始化的函数为pthread_attr_init,这个函数必须在pthread_create函数之前调用。之后须用pthread_attr_destroy函数来释放资源。线程属性主要包括如下属性:作用域(scope)、栈尺寸(stack size)、栈地址(stack address)、优先级(priority)、分离的状态(detached state)、调度策略和参数(scheduling policy and parameters)。默认的属性为非绑定、非分离、缺省1M的堆栈、与父进程同样级别的优先级。

所用函数

 int pthread_attr_init(pthread_attr_t *attr);//初始化
 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);//设置分离非分离属性
 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachst
  ..........还有很多函数
 int pthread_attr_destroy(pthread_attr_t *attr);//销毁

使用

#include
#include
#include
#include
#include
#include
void*tfn(void*argv)
{
    printf("thread : pid=%d,tid=%lun",getpid(),pthread_self());
    return NULL;
}
int main()
{
    pthread_attr_t attr;
    pthread_t tid;
    int ret=pthread_attr_init(&attr);   //初始化
    if(ret!=0)
    {
        fprintf(stderr,"attr_init error:%sn",strerror(ret));
        exit(1);
    }
    ret=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//设置线程属性为分离属性
    if(ret!=0)
    {
        fprintf(stderr,"attr_setdeatachstate error:%sn",strerror(ret));
        exit(1);
    }
    ret=pthread_create(&tid,&attr,tfn,NULL);
    if(ret!=0)
    {
        fprintf(stderr,"attr_create error:%sn",strerror(ret));
        exit(1);
    }
    ret=pthread_attr_destroy(&attr);//销毁
    if(ret!=0)
    {
        fprintf(stderr,"attr_destroy error:%sn",strerror(ret));
        exit(1);
    }
    sleep(1);
    ret=pthread_join(tid,NULL);//测试是否成功分离线程
    if(ret!=0)
    {
        fprintf(stderr,"create error:%sn",strerror(ret));
        exit(1);
    }
       return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/869379.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号