unix多进程多线程

概要

线程和进程是两种不同的并发执行单元,它们都可以实现多任务的执行,但是有各自的特点和区别。

  • 线程是操作系统独立调度和执行的基本单位,它是进程的一个组成部分,一个进程可以包含多个线程,它们共享进程的地址空间、数据和资源。线程有自己的栈、寄存器和程序计数器,它们之间可以直接通信和协作。
  • 进程是程序在某个数据集合上的一次运行活动,也是操作系统进行资源分配和保护的基本单位。进程有自己独立的地址空间、数据和资源,进程之间通过通信机制(如管道、信号、消息队列等)来交换信息。

要调用线程和进程,需要使用不同的方法,具体取决于操作系统和编程语言。一般来说,有以下几种常见的方法:

  • 在 Linux 系统中,可以使用 fork() 函数来创建一个新的进程,该函数会复制当前进程的地址空间、数据和资源,并返回一个进程标识符(PID)。父进程和子进程可以通过 PID 来区分自己,并继续执行不同的代码。可以使用 wait() 函数来等待子进程结束,并获取其返回值。可以使用 exec() 系列函数来在子进程中执行另一个程序,并替换其地址空间、数据和资源。
  • 在 Linux 系统中,可以使用 pthread 库来创建和管理线程。pthread 库提供了一系列函数来创建、终止、同步、互斥和调度线程。可以使用 pthread_create() 函数来创建一个新的线程,并指定其要执行的函数和参数。可以使用 pthread_join() 函数来等待一个线程结束,并获取其返回值。可以使用 pthread_exit() 函数来终止当前线程,并返回一个值。
  • 在 Windows 系统中,可以使用 CreateProcess() 函数来创建一个新的进程,并指定其要执行的程序、命令行参数、安全属性、优先级等。该函数会返回一个进程句柄(HANDLE),用于标识和控制该进程。可以使用 WaitForSingleObject() 函数来等待一个进程结束,并获取其退出码。可以使用 TerminateProcess() 函数来强制终止一个进程,并指定其退出码。
  • 在 Windows 系统中,可以使用 CreateThread() 函数来创建一个新的线程,并指定其要执行的函数和参数。该函数会返回一个线程句柄(HANDLE),用于标识和控制该线程。可以使用 WaitForSingleObject() 函数来等待一个线程结束,并获取其退出码。可以使用 ExitThread() 函数来终止当前线程,并返回一个值。
  • 在 C 语言中,可以使用 system() 函数来调用操作系统命令,并创建一个新的进程来执行该命令。该函数会阻塞当前进程,直到命令执行完毕,并返回命令的退出码。
  • 在 C++ 语言中,可以使用 std::thread 类来创建和管理线程。std::thread 类提供了构造函数、析构函数、移动赋值运算符等方法来创建、销毁、转移线程对象。可以向构造函数传递一个可调用对象(如函数指针、函数对象、lambda 表达式等)和参数,来指定线程要执行的任务。可以使用 join() 方法来等待一个线程结束,并获取其返回值。可以使用 detach() 方法来分离一个线程,使其在后台运行。

进程和线程的概念

  • 进程是程序在某个数据集合上的一次运行活动,也是操作系统进行资源分配和保护的基本单位。
  • 线程是进程中的一个执行单元,是操作系统进行调度的基本单位。
    进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。
  • 而线程是共享进程中的数据的,使用相同的地址空间,因此 CPU 切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

进程和线程的状态转换

  • 进程有三种基本状态:就绪态、运行态和阻塞态。就绪态表示进程已经准备好运行,等待 CPU 分配时间片;运行态表示进程正在占用 CPU 执行;阻塞态表示进程因为等待某些事件而暂停执行,让出 CPU 资源。
  • 线程也有类似的状态转换,但是线程的阻塞不会导致整个进程的阻塞,同样线程的就绪也不一定会立即运行。
  • 进程和线程的状态转换都需要操作系统的干预,操作系统通过进程控制块(PCB)来管理和调度进程,通过原语来实现进程状态转换的功能。

进程和线程的通信方式

  • 进程间通信(IPC)需要借助操作系统提供的服务,常见的方式有管道、消息队列、信号量、共享内存、套接字等。
  • 线程间通信(TIC)由于共享同一进程的资源,可以直接读写数据,无需操作系统干预。但是为了避免数据不一致或冲突,需要使用互斥锁、信号量等同步机制来保证线程安全。

C++中的线程进程调用

C++11标准提供了头文件来支持多线程编程,可以使用std::thread类来创建和管理线程。

下面是一些C++中的线程或进程调用示例:

  • 创建一个简单的线程,执行一个无参数的函数:
#include <iostream>
#include <thread>void thread_fun() // 线程要执行的函数
{std::cout << "Hello, thread!" << std::endl;
}int main()
{std::thread t(thread_fun); // 创建一个线程对象t,并传入要执行的函数t.join(); // 等待线程t结束return 0;
}
  • 创建一个带参数的线程,执行一个有参数的函数:
#include <iostream>
#include <thread>void thread_fun(int x) // 线程要执行的函数,有一个整型参数
{std::cout << "The parameter is " << x << std::endl;
}int main()
{std::thread t(thread_fun, 42); // 创建一个线程对象t,并传入要执行的函数和参数t.join(); // 等待线程t结束return 0;
}
  • 创建多个线程,共享同一个函数,并使用互斥锁来保护共享数据:
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx; // 创建一个互斥锁对象
int counter = 0; // 创建一个共享数据void thread_fun() // 线程要执行的函数
{mtx.lock(); // 上锁,保护共享数据counter++; // 修改共享数据std::cout << "Thread " << counter << " is running" << std::endl;mtx.unlock(); // 解锁,释放共享数据
}int main()
{const int N = 10; // 定义线程数量std::thread threads[N]; // 创建一个线程数组for (int i = 0; i < N; i++){threads[i] = std::thread(thread_fun); // 为每个线程对象分配要执行的函数}for (int i = 0; i < N; i++){threads[i].join(); // 等待每个线程结束}return 0;
}
  • 在Linux系统中,创建一个新的进程,并在子进程中执行另一个程序:
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>int main()
{pid_t pid = fork(); // 创建一个新的进程,返回进程标识符if (pid == -1) // fork失败{std::cerr << "Fork error" << std::endl;return -1;}else if (pid == 0) // 子进程{std::cout << "Child process, pid = " << getpid() << std::endl;execl("/bin/ls", "ls", "-l", NULL); // 在子进程中执行ls命令,替换子进程的地址空间、数据和资源std::cerr << "Exec error" << std::endl; // 如果exec成功,这一行不会被执行return -1;}else // 父进程{std::cout << "Parent process, pid = " << getpid() << std::endl;int status;wait(&status); // 等待子进程结束,并获取其返回值std::cout << "Child process exited with status = " << status << std::endl;return 0;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/74420.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Microsoft Edge网页视频播放绿屏解决方法(B站)

一&#xff1a;问题&#xff0c;在B站观看视频时有绿色条纹 二&#xff1a;查找原因&#xff0c;未知 三&#xff1a;解决方法 三.1网页设置关闭硬件加速 三.2 点击视频播放下的 “小齿轮”&#xff0c;然后点击“更多播放设置” 把播放策略 “默认” 改为“AVC” 四&…

Tomcat配置域名和端口

Tomcat配置域名和端口 1.进入tomcat文件夹2. cd 到你的tomcat下3. 修改server.xml文件中监听端口4. 重启tomcat 1.进入tomcat文件夹 2. cd 到你的tomcat下 3. 修改server.xml文件中监听端口 继续修改server.xml中Host 4. 重启tomcat 进入bin ./shutdown.sh ./startup.sh …

etcd分布式存储

etcd分布式存储 etcd简介etcd下载安装etcd常用命令etcd配置参数etcd集群golang操作etcd

C++ map clear内存泄漏问题

map值存的是指针 map自带的clear()函数会清空map里存储的所有内容&#xff0c;但如果map值存储的是指针&#xff0c;则里面的值不会被清空&#xff0c;会造成内存泄漏&#xff0c;所以值为指针的map必须用迭代器清空。 使用erase迭代删除 迭代器删除值为指针的map&#xff0c…

rrweb入门

rrweb 背景 rrweb 是 record and replay the web&#xff0c;是当下很流行的一个录制屏幕的开源库。与我们传统认知的录屏方式&#xff08;如 WebRTC&#xff09;不同的是&#xff0c;rrweb 录制的不是真正的视频流&#xff0c;而是一个记录页面 DOM 变化的 JSON 数组&#x…

vue elementui 组合式 api 对于容器的滑动条的位置的获取与设置。切换页面可以保持原来的容器里的滑动条位置不变

需要使用 addEventListener 的方法获取滑动条的位置 xxx.vue 页面是一直缓存的&#xff0c;所以使用路由进入钩子&#xff08;onActivated&#xff09;设置滑动条的位置 App.vue: ...<el-container><router-view v-slot"{ Component }"><keep-alive…

Python基础篇(07):高阶函数lambda、zip、map、filter、reduce和函数注解

一、匿名函数 lambda 表达式 1、格式 lambda 参数: 表达式 冒号前是参数&#xff0c;可以有多个&#xff0c;用逗号隔开冒号右边的为表达式返回值是一个函数对象 2、举例&#xff1a;一个最简单的lambda函数 add lambda x, y: x y print(type(add)) # <class func…

Ubuntu 22.04 安装 Docker Engine

Install Docker Engine on Ubuntu | Docker Docs 比较方便的安装方式为通过 Apt Repo 来安装&#xff0c;需要三大步&#xff1a; 1. 预备仓库信息&#xff1a; 逐行执行一下命令 # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificat…

R语言---使用runway进行机器学习模型性能的比较

R语言—使用runway进行机器学习模型性能的比较 #dataloadrm(list=ls())#librarylibrary(dcurves)library(gtsummary)library(tidyverse)library(mlr3verse)library(tidyverse)library(data.table)</

【鲁棒电力系统状态估计】基于投影统计的电力系统状态估计的鲁棒GM估计器(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

SpringCloud Alibaba 入门到精通 - Nacos

SpringCloud Alibaba 常用组件 一、基础结构搭建1.父工程创建2.子工程创建 二、Nacos&#xff1a;注册中心1.服务端搭建2.注册中心-客户端搭建3.注册中心-管理页面4.注册中心-常用配置5.注册中心-核心功能总结 三、Nacos注册中心集成Load Balancer 、OpenFeign1.Nacos客户端集成…

一键部署k8s集群

前置动作 关闭防火墙 systemctl disable firewalld && systemctl stop firewalld 关闭SELinux sed -i s#SELINUXenforcing#SELINUXdisabled#g /etc/selinux/config && grep SELINUXdisabled /etc/selinux/config setenforce 0 getenforce 关闭swap # 关闭…

前端面试题JS篇(4)

浏览器缓存 浏览器缓存分为强缓存和协商缓存&#xff0c;当客户端请求某个资源时&#xff0c;获取缓存的流程如下&#xff1a; 先根据这个资源的一些 http header 判断它是否命中强缓存&#xff0c;如果命中&#xff0c;则直接从本地获取缓存资源&#xff0c;不会发请求到服务…

c语言练习44:深入理解strstr

深入理解strstr strstr作用展示&#xff1a; #include <stdio.h> #include <string.h> int main() {char str[] "This is a simple string";char* pch;pch strstr(str, "simple");/*strncpy(pch, "sample", 6);*/printf("%s…

Android逆向学习(一)vscode进行android逆向修改并重新打包

Android逆向学习&#xff08;一&#xff09;vscode进行android逆向修改并重新打包 写在前面 其实我不知道这个文章能不能写下去&#xff0c;其实我已经开了很多坑但是都没填上&#xff0c;现在专利也发出去了&#xff0c;就开始填坑了&#xff0c;本坑的主要内容是关于androi…

Scrum认证高级Scrum Master (A-CSM) 认证培训课程

课程简介 高级ScrumMaster (Advanced Certified ScrumMaster, A-CSM) 认证课程是国际Scrum联盟推出的进阶级Scrum认证课程&#xff0c;是Scrum Master通往专业级敏捷教练必经的学习路径。 在ScrumMaster&#xff08;CSM&#xff09;认证课程中&#xff0c;您学习到了Scrum的价…

Centos 6.5 升级到Centos7指导手册

一、背景 某业务系统因建设较早&#xff0c;使用的OS比较过时&#xff0c;还是centos6.5的系统&#xff0c;因国产化需要&#xff0c;需将该系统升级到BClinux 8.6&#xff0c;但官方显示不支持centos 6.x升级到8&#xff0c;需先将centos6.5升级到centos7的最新版&#xff0c…

50道基础数据结构面试题

程序员必备的50道数据结构和算法面试题 在本文中&#xff0c;将分享一些常见的编程面试问题&#xff0c;这些问题来自于不同经验水平的程序员&#xff0c;囊括从刚大学毕业的人到具有一到两年经验的程序员。 编码面试主要包括数据结构和基于算法的问题&#xff0c;以及一些诸…

华为OD机试 - 战场索敌 - 深度优先搜索dfs算法(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、深度优先搜索dfs五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明4、如果增加目标敌人数量K为55、来&#xff0c;上强度 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 有一个大小是N*M…

【postgresql 基础入门】从了解数据库访问权限,访问数据库,到认识数据库的所有者及属性,从此打开了数据库使用的大门

数据库操作 ​专栏内容&#xff1a; postgresql内核源码分析手写数据库toadb并发编程 ​开源贡献&#xff1a; toadb开源库 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君…