LIUNX学习-线程

发布于:2025-03-06 ⋅ 阅读:(7) ⋅ 点赞:(0)
 线程概念

一个进程需要访的大部分资源,诸如自身的代码、数据、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;
}