当前位置: 首页 > news >正文

LIUNX学习-线程

 线程概念

一个进程需要访的大部分资源,诸如自身的代码、数据、new\malloc的空间数据、命令行参数和环境变量、动态库、甚至是系统调用访问内核代码…都是通过虚拟地址空间来访问的。换而言之,进程地址空间是进程的资源窗口!!
    进程创建费时费力。在创建时,我们需要为进程创建PCB、地址空间、页表、将进程自身的代码和数据换入内存并建立映射、将进程PCB状态改为R状态、添加带运行队列中…  但如果现在已经存在一个线程了,我仅仅将进程PCB复制多份,然后让所有“进程”PCB全部指向同一个虚拟地址空间。然后通过技术手段,将虚拟地址空间合理分配给每一个“进程”。当CPU调度执行该“”进程“时,只会执行原本进程中的一部分代码和数据,执行我们要执行任务的一部分任务,我们将这种比传统“进程”更加轻量化的进程就称为线程!!

主线程和子线程
共享:
.text
.bss
.data
动态加载区
环境变量
命令行参数
-通信:全局变量,堆
不共享
一共五个线程,栈区被平均分成五块
Linux下: 线程就是进程-轻量级进程
对于内核来货,线程就是进程
多进程和多线程的区别:
多进程: 始终共享的资源 代码、文件描述符、内存映射区--mmap
多线程:始终共享的资源:堆、全局变量,节省资源
查看指定线程的LWP号:
线程号和线程ID是有区别的
线程号是给内核看的
查看方式
找到程序的进程ID
ps -Lf pid
线程的创建

 

#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
void * myfunc(void *arg)
{
        printf("child pthread id : %ld\n",pthread_self());
}
int main()
{
        pthread_t  pthid;
        int ret;
        ret=pthread_create(&pthid,NULL,myfunc,NULL);
        if(ret!=0)
        {
        printf("error number is %d\n",ret);
        printf("%s\n",strerror(ret));
        }
          printf("parent pthread id : %ld\n",pthread_self());
        for(int i=0;i<5;i++)
        {
                printf("i=%d\n",i);
        }
        sleep(2);
        return 0;
}

使用sleep()函数先防止主函数1进程结束,导致子进程消失

单个线程退出 --pthread_exit

#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
void * myfunc(void *arg)
{
        printf("child pthread id : %ld\n",pthread_self());
        exit(0);
}
int main()
{
        pthread_t  pthid;
        int ret;
        int i=0;
        ret=pthread_create(&pthid,NULL,myfunc,NULL);
        if(ret!=0)
        {
        printf("error number is %d\n",ret);
        printf("%s\n",strerror(ret));
        }
          printf("parent pthread id : %ld\n",pthread_self());
        while(i<10){
                printf("i=%d\n",i);
                i++;
        }
        pthread_exit(NULL);
        sleep(2);
        return 0;
}

 

阻塞等待线程退出,获取线程退出状态--pthread_join
#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int num=100;
void * myfunc(void *arg)
{
        printf("child pthread id : %ld\n",pthread_self());
//      exit(0);
        for(int i=0;i<5;i++)
        {
                printf("child pthread %d\n",i);
        }
        pthread_exit(&num);
}
int main()
{
        pthread_t  pthid;
        int ret;
        int i=0;
        ret=pthread_create(&pthid,NULL,myfunc,NULL);
        if(ret!=0)
        {
        printf("error number is %d\n",ret);
        printf("%s\n",strerror(ret));
        }
          printf("parent pthread id : %ld\n",pthread_self());
          void*ptr=NULL;
          pthread_join(pthid,&ptr);
          printf("num=%d\n",*(int*)ptr);
      while(i<10){
                printf("i=%d\n",i);
                i++;
        }
        sleep(2);
        return 0;
}
                                

 

 线程分离--pthread_detach

杀死(取消)线程--pthread_cancel

比较两个线程ID是否相等(预留函数) --pthread_equal 

线程的分离属性

1.分离属性是属于线程的属性,有了分离属性的线程,是不需要别的线程去接合自己的(回收自己的资源)。
但是虽然是分离的,但是如果进程退出,该线程还是会退出的。

2.分离属性的特点

该线程的资源,不需要被别的线程回收(接合),资源是由系统来回收的。

分离属性    -->  不需要被的线程去调用pthread_join()来回收资源。
非分离属性  -->  需要被别的线程去调用pthread_join来回收资源。

通过属性设置线程的分离
1.线程属性类型: pthread_attr_t attr;
2.线程属性操作函数:
对线程属性变量的初始化
int pthread_attr_init(pthread_attr_t* attr);
设置线程分离属性
int pthread_attr_setdetachstate(
pthread_attr_t* attr,
int detachstate
);
参数:
attr : 线程属性
detachstate
PTHREAD_CREATE_DETACHED(分离)
PTHREAD_CREATE_JOINABLE(非分离)
释放线程资源函数
int pthread_attr_destroy(pthread_attr_t* attr)
#include <stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
void * myfunc(void *arg)
{
        printf("child pthread id : %ld\n",pthread_self());
}
int main()
{
        pthread_t  pthid;
        int ret;
        pthread_attr_t arr;
        pthread_attr_init(&arr);
        pthread_attr_setdetachstate(&arr,PTHREAD_CREATE_DETACHED);
        ret=pthread_create(&pthid,&arr,myfunc,NULL);
        if(ret!=0)
        {
        printf("error number is %d\n",ret);
        printf("%s\n",strerror(ret));
        }
          printf("parent pthread id : %ld\n",pthread_self());
        for(int i=0;i<5;i++)
        {
                printf("i=%d\n",i);
        }
        sleep(2);
        pthread_attr_destroy(&arr);
        return 0;
}

 

相关文章:

  • 【3DMAX室内设计】2D转3D平面图插件2Dto3D使用方法
  • TomcatServlet
  • MyBatis-Plus 自定义 SQL 和复杂查询
  • 迭代器模式:遍历集合的艺术
  • flink集成tidb cdc
  • Redis - 解读三种方案实现Redis跨机房数据同步
  • QT-绘画事件
  • AutoGen学习笔记系列(七)Tutorial - Managing State
  • JAVA编程【jvm垃圾回收的差异】
  • PHP之特性
  • LLM-ESR实验代码讲解
  • 蓝桥与力扣刷题(蓝桥 旋转)
  • 学习笔记-AMD CPU 命名
  • 分库分表 MyBatis的拦截器(Interceptor)在 SQL 执行前动态修改表名
  • 系统架构评估中的重要概念
  • java数据结构_再谈String_10
  • 索引(MySQL)
  • C# iText 抽取PDF页特定区域文本内容
  • MySQL:MySQL的数据类型
  • Autojs无线连接vscode方法
  • 秦皇岛建设局网站/seo有哪些优化工具
  • 网站建设框架文档/免费网站推广软文发布
  • 微信平台服务电话/seo基础入门教程
  • 检测网站的seo效果/b2b自动发布信息软件
  • 在哪些网站上做推广好/竞价推广账户竞价托管公司
  • 外贸公司网站建设方案/代写文案平台