首页 > 系统相关 >linux高级编程(线程)(1)

linux高级编程(线程)(1)

时间:2024-07-01 21:28:05浏览次数:24  
标签:linux attr void 编程 线程 pthread 进程 函数

虚拟地址:

线程:

        概念:线程是轻量级进程,一般是一个进程中的多个任务。
        进程是系统中最小的资源分配单位。(竞争计算机资源的最小单位)(进程能分配硬件资源,线程不行)线程是系统中最小的执行单位。


    特征:
    1、共享资源(除了栈区都共享)-->每个进程有独立的栈区,其他空间其实都用的是所从属的进程的,有效减少内存开销
    2、效率高  30%
    3、三方库: pthread  clone   posix
            3.1 编写代码头文件: pthread.h
            3.2 编译代码加载库: -lpthread   library 
            libpthread.so
            gcc 1.c -lpthread 

缺点:
    1,线程和进程相比,稳定性,稍微差些(一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程稳定。)
    2,线程的调试gdb,相对麻烦些。

线程与进程区别:
    变量开销:进程:3G(物理内存总量),线程:8M(单个程序栈的最大空间)

    资源:
        线程比进程多了共享资源。  IPC(进程间通信)
        线程又具有部分私有资源。
        进程间只有私有资源没有共享资源。
    空间:
        进程空间独立,不能直接通信。
        线程可以共享空间,可以直接通信。

线程的设计框架 

   创建多线程 --> 线程空间操作 --> 线程资源回收

线程创建:pthread_create():

int pthread_create(
        pthread_t *thread, const pthread_attr_t *attr,
        void *(*start_routine) (void *), void *arg);
    功能:该函数可以创建指定的一个线程。
    参数:thread 线程id,需要实现定义并由该函数返回。
          attr   线程属性,一般是NULL,表示默认属性。
          start_routine 指向指针函数的函数指针。
                  本质上是一个函数的名称即可。称为
                  回调函数,是线程的执行空间。

          arg  回调函数的参数,即参数3的指针函数参数。
          如果想要传多个参数:使用结构体
          返回值:成功 0
          失败 错误码

注:

       一次pthread_create执行只能创建一个线程。
      每个进程至少有一个线程称为主线程。
      主线程退出则所有创建的子线程都退出。 
      主线程必须有子线程同时运行才算多线程程序。
      线程id是线程的唯一标识,是CPU维护的一组数字。
      pstree 查看系统中多线程的对应关系。
      多个子线程可以执行同一回调函数。

pthread_self():

pthread_t pthread_self(void);
   功能:获取当前线程的线程id
   参数:无
   返回值:成功 返回当前线程的线程id
                 失败  -1; 

线程退出:

自行退出-->自杀-->exit()

void pthread_exit(void *retval);  //与return的效果类似
        功能:子线程自行退出
        参数: retval 线程退出时候的返回状态,临死遗言。
        返回值:无

强制退出-->他杀-->pthread_cancel()

int pthread_cancel(pthread_t thread);
        功能:请求结束一个线程
        参数:thread 请求结束一个线程tid
        返回值:成功 0
                      失败 -1;

pthread_join()

 int pthread_join(pthread_t thread, void **retval);    
     功能:阻塞回收。通过该函数可以将指定的线程资源回收,该函数具有
          阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
     参数:thread  要回收的子线程tid
        retval  要回收的子线程返回值/状态。-->ptread_exit(值);
     返回值:成功 0
                   失败 -1;

为什么要用ret要使用二级void指针:

因为ret期望来存储类似于函数指针,字符串(字符串使用字符数组存储)的值,这种变量本身就是一级指针,如果我们要在传参这种操作中能使被调修改主调,必须使用*运算,所以我们传进去的二级指针

期望的传参操作:

void* ret;
pthread_create(&tid,NULL,th,NULL);
pthread_join(tid,&ret); //传入一级指针地址
printf("ret %s\n",(char *)ret); //转换为需要的类型
printf("ret %d\n",*((char *)ret)); //取两次*运算

子线程的回收策略:

1、如果预估子线程可以有限范围内结束则正常用pthread_join等待回收。
2、如果预估子线程可能休眠或者阻塞则等待一定时间后强制回收。
3、如果子线程已知必须长时间运行则,不再回收其资源。

期望传回的地址:

原理:子线程退出的时候,可以返回一个内存地址
      该值所在的内存中可以存储任何数据,只要
      地址存在,则数据都可以正常返回。
    
    地址有三种:
    0、栈区变量  错误,子线程结束该地址失效。
    1、全局变量  失去意义,本质可以直接访问。

所以可以传回的地址:

    2、静态变量 
    3、堆区变量

分离属性(attribute):

设置分离属性,目的线程消亡,自动回收空间。

pthread_attr_init

int pthread_attr_init(pthread_attr_t *attr);
    功能,初始化一个attr的变量
    参数:attr,需要变量来接受初始值
    返回:0  成功,
    非0 错误

 pthread_attr_destroy

int pthread_attr_destroy(pthread_attr_t *attr);
      功能:销毁attr变量。
      attr,属性变量
      返回:0  成功,
      非0 错误;

pthread_attr_setdetachstate

功能:把一个线程设置成相应的属性
    参数,attr,属性变量,有init函数初始化他。
    detachstate:有2个可选值,
    设置分离属性:
    PTHREAD_CREATE_DETACHED(分离线程)
    PTHREAD _CREATE_JOINABLE(非分离线程)

第二种设置分离属性的函数:pthread_deatch

int pthread_deatch(pthread_t thread);
    功能,设置分离属性
    参数,线程id号,填自己的id        

清理函数:

pthread_cleanup_push()

void pthread_cleanup_push(void (*routine)(void *), void *arg);
    功能:注册一个线程清理函数
    参数,routine,线程清理函数的入口
        arg,清理函数的参数。
    返回值,无

需要满足以下条件才会调用注册的回调函数:

1.线程被取消的时候(pthread_cancel)

2.线程主动退出的时候(pthread_exit)

3.pthread_cleanup_pop的参数为非0值(pthread_cleanup_pop)

pthread_cleanup_pop:

void pthread_cleanup_pop(int execute);
    功能:调用清理函数
    execute,非0  执行清理函数
        0 ,不执行清理
            
    返回值,无

标签:linux,attr,void,编程,线程,pthread,进程,函数
From: https://blog.csdn.net/qq_54094530/article/details/140086368

相关文章

  • 高编:线程(2)——同步与互斥
    一、互斥概念:   互斥===》在多线程中对临界资源的排他性访问。   互斥机制===》互斥锁 ===》保证临界资源的访问控制。   pthread_mutex_t mutex;   互斥锁类型       互斥锁变量内核对象框架:   定义互斥锁==》初始化锁=......
  • Linux基本技巧
    linux查看cpu占用率的方法查看单核CPU占用率,终端上输入“top”。查看多核CPU占用率,终端上输入“top”,进入界面再输入“1”。Linuxtop命令里面%CPU和cpu(s)的差别Cpu(s):所有用户进程占用整个cpu的平均值,由于每个核心占用的百分比不同,所以按平均值来算比较有参考意义。%CPU......
  • KUKA机器人中断编程2—中断相关的指令
    在进行中断编程时,涉及到多个指令,包括:DECL、ON、OFF、GLOBAL、BRAKE、RESUME等。1、中断声明事件和子程序通过INTERRUPTDECL...WHEN..DO..来定义。语法:INTERRUPTDECLPrioWHEN事件DO中断程序例如:INTERRUPTDECL19WHEN$IN[1]==TRUEDOstop1()其中,中断优......
  • 16_C语言编程基础
    目录C语言入门程序段和代码段C语言入门实例英文分号(;)注释标识符保留字C中的空格C数据类型基本类型sizeof获取存储字节void类型变量C数组C枚举C中的左值(lvalue)和右值(rvalue)C常量变量存储类型C常用关键字(保留字)宏定义#defineconst关键字static关......
  • Java进阶学习|Day4.Java多线程,线程池
    文章目录了解多线程CPU进程(Process)线程多线程开发多线程优点实现方式继承Thread类实现Runnable接口实现Callable接口线程状态转换线程状态线程调度调整线程优先级线程睡眠线程等待线程让步线程加入线程唤醒线程同步线程同步方式多线程间通信线程池了解线程池定义......
  • Vue组件化编程
    Vue组件化编程组件的定义:用来实现局部(特定)功能效果的代码集合(html/css/js/image)为什么使用组件:一个界面的功能很复杂作用:复用代码,简化项目编码,提高运行效率组件分为非单文件组件和单文件组件,在开发中一般使用单文件组件非单文件组件1.组件的基本用法组件的使用步骤有三步:定......
  • linux yum的安装与管理
    (学生填写)(一)yum配置本地源在使用yum安装之前是必须配置yum源的,在不能联网的情况下,可使用DVD光盘或ISO文件做本地yum源.建立光盘文件存放目录(/mnt/dvd)和创建光盘挂载点,如图1所示。 图1挂载光盘成功2.利用挂载光盘命令,已将光盘正常挂载好,如图2......
  • linux网络配置与管理
    1.Setup配置(centos7之后使用nmtui)首先,查看网卡的信息,是否有IP地址。如图所示:图1查看网卡信息进入set设置,在终端输入“setup”,点击“enter”键。如图所示:图2进入setup设置点击“enter”后,就进入了setup配置界面了,选择“网络配置”。如图所示:图3......
  • 用C++解决编程题目:角谷猜想
    学习目标:用C++编写简单的题目学习内容:#include<iostream>usingnamespacestd;intmain(){longlongn;cin>>n;while(n!=1){if(n%2==1){cout<<n<<"*3+1="<<n*3+1<<endl;n=3*n+1;......
  • Mojo — 适用于所有人工智能开发人员的编程语言
    Mojo语言是一个由人工智能公司Modular推出的全新编程语言,专为AI开发者设计。Mojo的语法与Python相似,但结合了Python的易用性和C语言的高性能,旨在解锁AI硬件的可编程性和AI模型的可扩展性。Modular这个公司则是一个非常年轻的新生AI创业公司,于2022年由ChrisLattner和TimDavi......