IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 线程控制:线程的创建 -> 正文阅读

[C++知识库]线程控制:线程的创建

线程控制

通过代码实现线程的创建/退出/等待/分离
进行线程控制的接口代码,都来自库函数,
也就是说,操作系统没有提供创建线程的接口,大佬们人为的使用库函数封装了一套线程库。
这套封装的线程库函数,提供线程的各种操作。
使用库函数创建一个线程(用户态),本质上线程就会在内核中创建一个轻量化的进程来实现程序的调度。
(pcb是一个task_struct结构体,存储在内核中,使用的是内核空间,想要访问pcb就得切换到内核态运行。)
在这里插入图片描述

创建:

int pthread_create(pthread_t* thread,const pthread_attr_t* attr,void* (*start_routine)(void* ),void* arg);
函数参数:
	thread:输出型参数,用于获取线程id -- 线程的操作句柄tid
	attr:线程属性,用于在创建线程的同时设置线程属性,暂时通常置NULL
	如: 栈大小  栈的溢出缓冲区大小  joinable属性/detach属性  阻塞信号的继承属性
	start_routine:函数指针,就是一个线程的入口函数 -- 线程运行的就是这个函数,函数运行完毕,这个线程就会退出。但主函数是不会等待这个线程执行完毕的。这个函数返回NULL。
	arg:通过线程的入口函数,传递给线程的参数。要作为参数传递给入口函数statr_routine。
返回值:成功返回0,失败返回非0值(错误编号)。

pthread_create接口的使用:

    1 /*=================================================================                                
    2  *
    3  *          这个demo用于线程的创建,体会线程的独立运行
    4  *
    5  *=================================================================*/
    6 
    7 
    8 #include<stdio.h>
    9 #include<unistd.h>     //sleep()
   10 #include<string.h>     
   11 #include<pthread.h>    //线程库接口头文件
   12 
   13 void* thr_start(void* arg)
   14 {
   15   strcpy(arg,"不好意思,你的参数被修改了~\n");
   16   while(1)
   17   {
   18     printf("I am thread~----%s",(char*)str);
   19     sleep(1);
   20   }
   21   return NULL;
   22 }
   23 
   24 
   25 
   26 int main()
   27 {
   28 
   29   //pthread(获取线程id,线程属性,线程入口函数,入口函数参数)
   30   pthread_t tid;      //pthread_t  : unsigned long long 无符号长整形
   31   char ptr[] = "wohenhao~\n";
   32   int ret = pthread_create(&tid,NULL,thr_start,(void*)ptr);
   33   if(ret != 0){
   34     printf("创建线程失败~\n");
   35     return -1;
   36   }
   37   printf("创建线程成功~\n");                                                                       
   38 
   39   while(1)
   40   {
   41     printf("nihaoa~---%s\n",ptr);
   42     sleep(1);
   43   }
   44   //一个主函数中只能出现一个死循环,所以这个循环是走不到的,
   45   //我们可以使用pthread_create创建普通线程,入口函数中写入死循环,
   46   //也就可以展示两个死循环,仅作使用pthread_create接口使用的展示例
   47   while(1)
   48   {
   49     printf("wobuhao~\n");
   50     sleep(1);
   51   }
   52                                                                                                    
   53   return 0;
   54 }
   

代码写好之后我们发现使用gcc编译提示pthread_create未定义,打开man pthread_create发现,
使用时这个接口时,在编译时应该使用-pthread链接。需要链接到pthread链接库。
在这里插入图片描述
注意这里的-l是为了适应平台,实际上直接加上-pthread也可以
在这里插入图片描述

库的链接使用:
	1.将库文件放在指定的目录下:/lib64/usr/lib64
	2.将库文件的路径添加到环境变量 LIBRARY_PATH中
	3.使用gcc -L选项指定库文件所在路径   -l 指定库文件名称。
	gcc默认是动态库	

运行之后我们就可以看到:
在这里插入图片描述
相当于把主线程main函数的局部变量地址传递给了普通线程:经过同一块虚拟地址空间,同一块页表,其实映射的也是同一块物理内存,谁改变了这个物理内存的数据,另一边也就随之改变。
tid:
在上面代码中,我们在创建线程之前,用pthread_t 定义了一个tid作为pthread_create函数的第一个参数。
我们打印一下这个tid:在这里插入图片描述
这是一个无符号长整形的数字。

那么这tid是什么呢?
其实,当我们创建一个线程时,会在虚拟地址空间上的栈区和堆区之间的共享区中开辟一块独属于这个线程的空间,
这块空间保存这个线程独有的数据,(比如线程的栈,线程在用户态的描述)。
这个空间就叫做这个线程的线程地址空间。tid就是这块空间的首地址。
系统通过向thread_create函数传入线程地址空间的首地址tid,来实现对这块空间的访问,从而实现对线程的控制。
所以这个tid在函数的说明中也叫线程的操作句柄。
在这里插入图片描述
这跟我们之前遇到的pid有什么关系/区别呢?
实际上,这两者并没有关联:

pid 是一个轻量级进程id,是内核中task_struct结构体中的id,
		task_struct -> pid : 轻量级进程id,也就是 ps -efL看到的LWP
		task_struct -> tgid: 线程组id,等于主线程id,也就是进程id,在ps -ef中表现为PID
同一个线程组的所有pcb都有一个相同的tgid

当我们程序运行起来时,使用ps-efL查看的PID 和 轻量化进程id与tid没有关系,tid仅用于对线程的操作
在这里插入图片描述

轻量级进程与线程:
在这里插入图片描述

其实轻量级进程和线程之间还是有区别的,在用户态创建一个线程时,由于系统没有提供线程的概念,
我们需要在内核态创建一个pcb,pcb通过找到tid这个空间首地址实现对线程的操作。
只是因为我们在创建一个线程的同时需要在内核中创建一个轻量化的进程,这才把线程叫做轻量化的进程。其实两者是有区别的。
ps -efL 的LWP就是内核中的pcb轻量化进程,而不是线程,这点要注意区分。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:20:07  更:2022-03-22 20:21:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:39:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码