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

线程控制

POSIX线程库

  • 与线程有关的函数构成了⼀个完整的系列,绝⼤多数函数的名字都是以“pthread_”打头的
  • 要使⽤这些函数库,要通过引入头文件<pthread.h>
  • 链接这些线程函数库时要使⽤编译器命令的“-lpthread”选项   eg: g++ -o $@ $^ -lpthread
  • 这个pthread库是linux自带的原生线程库 , C++11也有线程<thread>库,在Linux上本质就是封装了<pthread>库,
  • C++11 的 <thread>库 是跨平台的,在 Windows 上可能封装 CreateThread,在 macOS 上封装 pthread,在 Linux 上通常封装 pthread

创建线程

功能:创建⼀个新的线程
原型:
 int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *
(*start_routine)(void*), void *arg);
 
参数:
     输出型参数thread:返回线程ID
     attr:设置线程的属性,attr为NULL表⽰使⽤默认属性
     start_routine:是个函数地址,线程启动后要执⾏的函数
     arg:传给线程启动函数的参数
 
返回值:成功返回0;失败返回错误码(错误码一般大于0)

vfork已经基本被废除了

在linux内核看来 ,只有LWP ,所以向外只提供了clone一种系统调用, 通过封装clone, fork可以创建子进程 ,pthread_creat可以创建线程.

但是在Windows内核下,提供了创建进程的syscall 和创建线程的syscall (因为windos中确实单独实现了线程 和进程) linux下只有LWP

错误检查:

  • 传统的⼀些函数是,成功返回0,失败返回-1,并且对全局变量errno赋值以指⽰错误。
  • pthreads函数出错时不会设置全局变量errno(⽽⼤部分其他POSIX函数会这样做)。⽽是将错误代码通过返回值返回
  • pthreads同样也提供了线程内的errno变量,以⽀持其它使⽤errno的代码。对于pthreads函数的错误,建议通过返回值l来判定,因为读取返回值要⽐读取线程内的errno变量的开销更⼩

创建一个线程

#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<string>

void* routine (void* args)
{
    //static_cast 是 C++ 中的 静态类型转换运算符,用于在 编译时 进行类型检查的显式转换。它比 C 风格的强制转换 (type)value 更安全
    //使用方法:static_cast<目标类型>(表达式)
    std::string name = static_cast<const char *>(args);// 将 args(某种类型)显式转换为 const char *,并用它构造一个 std::string 对象 name
    while(true)
    {
        std::cout<<"我是子线程 我的名字是 "<<name<<std::endl;
        sleep(1);
    }
    return 0;
}

int main()
{
    pthread_t tid;
    int n =pthread_create(&tid ,nullptr ,routine,(void*)"thread-1");
    if(n!=0 )
    {
        std::cout<<"creat thread error"<<std::endl;
        return 1;
    }

    while(true)
    {
        std::cout<<"我是main线程 "<<std::endl;
        sleep(1);
    }
    return 0;
}

每个线程都有自己的ID ,在创建时就以第一个参数形式输出了,也可以使用函数pthread_self( ) 获取自己线程的ID

两个线程同时访问同一个公共资源有可能引发错误(像显示器打印,在不加保护的情况下,显示器也是公共资源)下面可以看到打印错乱,就是这个原因,就是我们以前讲的重入.

我们可以看到main线程和子线程的ID不同

总结:

  • 新线程和main线程谁先运行 ,不确定
  • 线程要瓜分进程的资源,包括时间片
  • 不加保护的情况下 ,显示器文件就是公共资源
  • 对于多线程代码 ,进程内的函数 ,被所有线程共享,只要这个函数不使用全局变量(显示器文件就是全局变量),就是安全的
  • 全局变量能被此进程中的全部线程看到
  • 一旦一个线程出现异常,进程就崩了(被信号杀死了),其它线程也就全崩了  例如:一个线程中使用了野指针 ,查页表时失败了,MMU报错 ,导致CPU触发软中断 ,OS发送信号杀死进程.
  • 线程创建后也是要被等待和回收的(主线程像父进程一样一定是最后退出的)

等待进程

相关文章:

  • Node.js EventEmitter 深入解析
  • 从零开始学Python游戏编程17-函数2
  • 手机静态ip地址怎么获取?方法与解析‌
  • ESModule和CommonJS在Node中的区别
  • windows上opencv编译cuda版本
  • java学习笔记14——网络编程
  • CesiumEarth卫星影像/电子地图等二维切片数据制作
  • AI重构知识生态:大模型时代的学习、创作与决策革新
  • 基于队列构建优先级抢占机制的LED灯框架设计与实现
  • 新闻发稿软文发布投稿选择媒体时几大注意
  • 企业使用文档加密系统的两个重要原因。
  • 【OSG学习笔记】Day 2: 场景图(Scene Graph)的核心概念
  • CUDA 工具链将全面原生支持 Python
  • Odrive0.5.1-FOC电机控制 arm_cos_f32.cpp arm_sin_f32.cpp代码实现(二)
  • ChatGPT的GPT-4o创建图像Q版人物提示词实例展示
  • `mpi4py` 是什么; ModuleNotFoundError: No module named ‘mpi4py
  • SQL练习题
  • 智慧医院常用的子系统介绍 51-100
  • C语言学习记录(14)自定义类型:联合和枚举
  • ABAP小白开发操作手册+(十)验证和替代——下
  • 深圳建设工程网/北京seo服务行者
  • 做商城网站需要办理什么/如何制作网站链接
  • 帮推广平台/广州seo成功案例
  • 天津市工程建设公众信息网官网/武汉seo网站推广培训
  • 网站上文章分享的代码怎么做的/西安分类信息seo公司
  • 网站怎么公安备案/正安县网站seo优化排名