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

12.线程(一)

一.SIGCHLD信号补充

应该子进程退出的时候,系统默认对其的信号是Ign的,所以我们看不到对应的反应

#include <iostream>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h> // 注意:原代码中使用了sleep函数,需包含此头文件
#include <wait.h>void handler(int signo)
{std::cout << "get a sig: " << signo << std::endl;
}int main()
{signal(SIGCHLD,handler);if(fork() == 0){sleep(5);std::cout << "子进程退出" << std::endl;exit(0);}while(true){sleep(1);}return 0;
}

所以,现在我们对应的子进程退出时,确实会给父进程发送信号,我们就能基于信号,来进行回收子进程

#include <iostream>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h> // 注意:原代码中使用了sleep函数,需包含此头文件
#include <wait.h>void handler(int signo)
{std::cout << "get a sig: " << signo << std::endl;pid_t rid = ::waitpid(-1,nullptr,0);if(rid > 0){std::cout << "子进程退出了,回收成功,child id: " << rid << std::endl;}
}int main()
{signal(SIGCHLD,handler);if(fork() == 0){sleep(5);std::cout << "子进程退出" << std::endl;exit(0);}while(true){sleep(1);}return 0;
}

问题一:

如果是多个子进程一起退出呢?

#include <iostream>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h> // 注意:原代码中使用了sleep函数,需包含此头文件
#include <wait.h>void handler(int signo)
{std::cout << "get a sig: " << signo << std::endl;pid_t rid = ::waitpid(-1,nullptr,0);if(rid > 0){std::cout << "子进程退出了,回收成功,child id: " << rid << std::endl;}
}int main()
{signal(SIGCHLD,handler);for(int i = 0;i < 10; i++){if(fork() == 0){sleep(5);std::cout << "子进程退出" << std::endl;exit(0);}}while(true){sleep(1);}return 0;
}

我们可以尝试循环wait,直到全部都回收

#include <iostream>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h> // 注意:原代码中使用了sleep函数,需包含此头文件
#include <wait.h>void handler(int signo)
{std::cout << "get a sig: " << signo << std::endl;while(true){pid_t rid = ::waitpid(-1,nullptr,0);if(rid > 0){std::cout << "子进程退出了,回收成功,child id: " << rid << std::endl;}else if(rid < 0){std::cout << "暂时:回收完毕" << std::endl;break;} }
}int main()
{signal(SIGCHLD,handler);for(int i = 0;i < 10; i++){if(fork() == 0){sleep(5);std::cout << "子进程退出" << std::endl;exit(0);}}while(true){sleep(1);}return 0;
}

问题二:

如果10个子进程,6个退出了,上面的代码会怎么办?

我们在等待第7个子进程的时候,会出现阻塞现象,我们要进行非阻塞等待

#include <iostream>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h> // 注意:原代码中使用了sleep函数,需包含此头文件
#include <wait.h>void handler(int signo)
{std::cout << "get a sig: " << signo << std::endl;while(true){pid_t rid = ::waitpid(-1,nullptr,WNOHANG);if(rid > 0){std::cout << "子进程退出了,回收成功,child id: " << rid << std::endl;}else if(rid == 0){std::cout << "退出的子进程已经全部回收了" << std::endl;break;}else{std::cout << "wait error" << std::endl;break;} }
}int main()
{signal(SIGCHLD,handler);for(int i = 0;i < 10; i++){if(fork() == 0){sleep(5);std::cout << "子进程退出" << std::endl;exit(0);}}while(true){sleep(1);}return 0;
}

还有一个简单操作,能直接对子进程进行回收

#include <iostream>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h> // 注意:原代码中使用了sleep函数,需包含此头文件
#include <wait.h>int main()
{//linux下 如果只想不产生僵尸,我们直接进行SIG_IGN就行了signal(SIGCHLD,SIG_IGN);for(int i = 0;i < 10; i++){if(fork() == 0){sleep(5);std::cout << "子进程退出" << std::endl;exit(0);}}while(true){sleep(1);}return 0;
}

但是我们的SIG_IGN只是在linux下有用,我们手动设置的IGN和默认的IGN是不一样的

二.线程概念

三.Linux下线程的概念

一个执行流就是一个线程

四.进程 vs 线程

五.接口验证

#include <iostream>
#include <unistd.h>
#include <pthread.h>//新线程
void* run(void* args)
{while(true){std::cout << "new thread" << std::endl;sleep(1);}return nullptr;
}int main()
{pthread_t tid;pthread_create(&tid,nullptr,run,(void*)"thread-1");//主线程while(true){std::cout << "main thread" << std::endl;sleep(1);}return 0;
}

如果是较新的版本,可能会自动带上我们对应的选项

"makefile"mythread:mythread.ccg++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:rm -rf mythread

这里确实是两个执行流

#include <iostream>
#include <unistd.h>
#include <pthread.h>//新线程
void* run(void* args)
{while(true){std::cout << "new thread, pid: " << getpid() << std::endl;sleep(1);}return nullptr;
}int main()
{std::cout << "我是一个进程: " << getpid() << std::endl;pthread_t tid;pthread_create(&tid,nullptr,run,(void*)"thread-1");//主线程while(true){std::cout << "main thread, pid: " << getpid() << std::endl;sleep(1);}return 0;
}

查看轻量级进程(ps -aL | grep mythread)

PID和LWP相同的就是我们对应的主线程,不相等的就是新线程

六.地址空间

1.分页式存储管理

2.多级页表

http://www.dtcms.com/a/581295.html

相关文章:

  • 如何做二维码跳转到网站建设网站专家
  • 前端i18n实现中英文切换
  • Java基础——常用算法4
  • SQL50+Hot100系列(11.7)
  • Python 第二十六节 多线程应用详细介绍及使用注意事项
  • 网站建设交接表wordpress编程视频教程
  • LeafView(轻量级电脑图片查看器) v3.8.1 中文绿色便携版
  • MySQL死锁问题分析与解决方案
  • shell中获取达梦信息方法示例
  • calibre QRC提取寄生参数
  • 【Hot100 |5-LeetCode 11. 盛最多水的容器】
  • 【MicroPython编程-ESP32篇】-DH11温度湿度传感器驱动
  • 字节deer-flow项目模块详解
  • 【Python】Python并发与并行编程图解
  • 清城网站seodiscuz自适应模板
  • 优秀网页设计网站是wordpress php开发
  • 内部网关协议——OSPF 协议(开放最短路径优先)(链路状态路由协议)
  • rman-08137:warning:archived log not deleted
  • 专业的开发网站建设价格虚拟云电脑
  • [Linux——Lesson21.进程信号:信号概念 信号的产生]
  • 浙江英文网站建设嘉兴高档网站建设
  • ERP与WMS一体化构建方案
  • python+django/flask的眼科患者随访管理系统 AI智能模型
  • 实战案例:用 Guava ImmutableList 优化缓存查询系统,解决多线程数据篡改与内存浪费问题
  • AR短视频SDK,打造差异化竞争壁垒
  • 什么是AR人脸特效sdk?
  • Angular由一个bug说起之二十:Table lazy load:防止重复渲染
  • 从0到1做一个“字母拼词”Unity小游戏(含源码/GIF)- 字母拼词正确错误判断
  • 网站建设自查情况报告做淘宝联盟网站要多少钱?
  • 重新思考 weapp-tailwindcss 的未来