多线程和多进程

这篇具有很好参考价值的文章主要介绍了多线程和多进程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

线程和进程

最近经常看到多线程和多进程,这两个概念在某些方向还是很像的,但是进程和线程到底有啥联系,又有啥区别,很多人并没有完全弄明白,最近学操作系统的时候,老师经常叫线程为进程的进程,看了网上的一些资料,也有把线程叫做轻量级进程的,今天我从Linux系统中的线程和进程来深入解释一下。

多线程和多进程

进程和线程的相同点要远远大于不同点。主要依据就是在 Linux 中,无论进程还是线程,都是抽象成了 task 任务,在源码里都是用 task_struct 结构来实现的,这点学过单片机freertos系统的也知道,在运行freertos的操作系统中stm32创建的多线程被称为任务。

struct task_struct {
 
 volatile long state;

 
 pid_t pid;
 pid_t tgid;

 
 struct task_struct __rcu *parent;
 struct list_head children; 
 struct list_head sibling;
 struct task_struct *group_leader; 

 
 int prio, static_prio, normal_prio;
 unsigned int rt_priority;

 
 struct mm_struct *mm, *active_mm;

 
 struct fs_struct *fs;

 
 struct files_struct *files;

 
 struct nsproxy *nsproxy;

 ...
}

这是一个任务控制块,在linux中进程和线程的所有字段即属性都是一样的,包括状态、pid、task 树关系、地址空间、文件系统信息、打开的文件信息等等字段,线程也都有,他们本质是一个东西,别忘了线程也叫做轻量级进程。

他们的关系与字段下面这两个字段密不可分

struct task_struct {
 ......
 pid_t pid;
 pid_t tgid;
}

pid学过操作系统的都知道这个是进程的id号

对于线程来说,如果我们一个进程创建了多个线程,那么每个线程的pid都是不同的,但是我们要知道这个线程是属于哪个进程,即由哪个进程所创建的,tgid就是为了表明该线程是哪个进程创建的,tgid的值是创建当前线程的进程的pid值。

多线程和多进程

创建进程

#include <iostream>
#include <unistd.h>
using namespace std;
int main() {
    pid_t pid = 5;
    
    pid = fork();
    if(pid < 0)
        cout << "Error in fork!" << endl;
    else if (pid == 0) cout << "I am Child1!Pid is " << pid << " B" << endl;
    else {
        cout << "I am Parent!Pid is " << pid << " A" << endl;
        pid_t pid2 = fork();
        if (pid2 == 0) cout << "I am Child2!Pid is " << pid2 << " C" << endl;
    }
    cout << "end." << endl;
    return 0;
}

创建进程调用的是fork()函数

创建线程

#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
void* thread_run(void* args)                                                                                                                             
{      
    const char* id = (const char*)args;      
    while(1){      
        printf("I am %s thread, %d\n", id, getpid());      
        sleep(1);      
    }      
}      
      
int main()      
{      
    pthread_t tid; //定义一个线程ID     
    pthread_create(&tid, NULL, thread_run, (void*)"thread 1"); 
    while(1){      
        printf("I am mian thread, %d\n",getpid());      
        sleep(1);      
    }      
    return 0;      
}

创建线程调用的是pthread_create()函数,

他们两个创建时调用的函数虽然不同,但是在底层的创建进程和线程调用的却是同一个函数,

进程创建

SYSCALL_DEFINE0(fork)
{
 return do_fork(SIGCHLD, 0, 0, NULL, NULL);
}
long do_fork(...)
{
 
 struct task_struct *p;
 p = copy_process(clone_flags, ...);
 ...
}

线程创建

create_thread (struct pthread *pd, ...)
{
 int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
    | CLONE_SETTLS | CLONE_PARENT_SETTID
    | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
    | 0);

 int res = do_clone (pd, attr, clone_flags, ...);
 ...
}
SYSCALL_DEFINE5(clone, ......)
{
 return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
}

可见无论是创建进程还是创建线程,都是调用内核中的do_fork()函数

多线程和多进程最大的区别就是他们所在的内存空间不同,多进程程序来说,每一个进程都有独立的地址空间,多进程只是,将父进程的空间复制了一份给子进程,而多线程程序中的所有线程都会共享其父进程的地址空间,子进程,子线程的变量参数改变时,父进程的变量参数并不受影响,因为子进程中的字段数据只是复制了父进程的创建子进程时的数据,而子线程不一样它和创建它的进程时共用一篇内存空间的,子线程中改变的值,同样会影响父进程。

得出结论进程和线程之间的根本区别在于其内存空间是否与创建它们的父进程是否共享文章来源地址https://www.toymoban.com/news/detail-467101.html

到了这里,关于多线程和多进程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • < Python全景系列-5 > 解锁Python并发编程:多线程和多进程的神秘面纱揭晓

    欢迎来到我们的系列博客《Python全景系列》!在这个系列中,我们将带领你从Python的基础知识开始,一步步深入到高级话题,帮助你掌握这门强大而灵活的编程语法。无论你是编程新手,还是有一定基础的开发者,这个系列都将提供你需要的知识和技能。   这是本系列的第五

    2024年02月05日
    浏览(38)
  • 小米妙享中心加载失败电脑能发现手机,手机能发现电脑,无法打开镜像画面,无法打开最近文件,能够看到但是无法打开,无法流转应用,无法共享屏幕

            本人是小米笔记本PRO14锐龙版WIN11系统,手机是小米14pro,电脑刚买来的时候都是可以正常在电脑投屏的,最近投屏总是失败报错,查了很久才解决这个问题可以正常投屏,所以发出来跟大家分享一下,以作参考。         首先要保证电脑上安装了小米妙享的最新

    2024年02月04日
    浏览(177)
  • 多线程基础详解(看到就是赚到)

    🎥 个人主页:Dikz12 📕格言:那些在暗处执拗生长的花,终有一日会馥郁传香 欢迎大家👍点赞✍评论⭐收藏 目录  创建线程  1.创建类继承Thread,重写run()  2.实现Runnable,重写run() 3.继承Thread,使用匿名内部类  4.使用lambda表达式(推荐) 线程启动  线程中断 1.手动设置标志位

    2024年02月19日
    浏览(50)
  • redis之单线程和多线程

    目录 1、redis的发展史 2、redis为什么选择单线程? 3、主线程和Io线程是怎么协作完成请求处理的? 4、IO多路复用 5、开启redis多线程 1、redis的发展史 Redis4.0之前是用的单线程,4.0以后逐渐支持多线程  Redis4.0之前一直采用单线程的主要原因有以下三个: 1、使用单线程模型使R

    2024年01月17日
    浏览(30)
  • 小米妙享中心非小米电脑加载失败电脑能发现手机,手机能发现电脑,无法打开镜像画面,无法打开最近文件,能够看到但是无法打开,无法流转应用,无法共享屏幕

    我这里使用的是ThinkPad T480电脑,该电脑已经是5年左右的老机器了,但是依然能够成功使用小米妙享,只是可能比起原装的功能没有那么全,至于原装是什么样,我也没有体会过,不做过多说明。安装方法很简单,下载小米妙享pc版.exe和机型破解库wtsapi32.dll,将这两个东西放

    2024年02月16日
    浏览(217)
  • 【Redis】Redis单线程和多线程

    Redis的版本很多,比如3.x、4.x、6.x等,版本不同,架构不同: 3.x版本,最早的版本,单线程 4.x版本,严格意义上来说不是单线程,负责处理客户端请求的线程是单线程,并且加了一些多线程(比如:异步删除) 2020年5月版本的6.0.x后及2022年出的7.0版本后,用一种全新的多线程

    2024年02月02日
    浏览(31)
  • VCSA6.7-VCSA7.0部署经常踩中的坑【 两个 】

    VCSA6.7-VCSA7.0部署经常踩中的坑【 俩! 】 坑1:vcsa【安装80%报错】·无法进入第二阶段 vcsa安装到达80%后,无法进入第二阶段,通过“IP:5480\\\"进入管理后台,系统处于崩溃报错状态! 坑2:vcsa安装到【第二阶】段部署报错【Internal Error】 第一阶段完成,进行第二阶段时报错:。

    2024年02月06日
    浏览(51)
  • 计算两个多边形的最近距离(MATLAB)

            本文意在介绍关于计算两组坐标点的最近距离的简单方法,可用此方法来计算两个多边形的最近距离以及距离最近的两个点。下面展示具体实例。 函数代码         该函数可以比较快速的计算两组坐标点之间的最小距离,并返回相应的坐标。缺点是只能计算整数

    2024年02月08日
    浏览(44)
  • 重定向爬虫和多线程爬虫

    重定向爬虫是指在抓取网页时,如果目标网站内部存在重定向机制,即当你访问一个网页时,服务器会把你重定向到另一个目标网页。重定向爬虫可以帮助我们发现这种重定向链接,从而更有效地抓取目标网站的内容。 要实现重定向爬虫,你需要在爬虫代码中添加重定向处理

    2024年02月11日
    浏览(48)
  • VS 多线程调试和多线程DLL调试选项功能

            区别是动态链接还是静态链接C运行时库(C runtime Library, CRT)。         如果是动态链接(MD/MDd),你的程序就依赖C运行时的动态链接库(比如VS2010的msvr100.dll),当你的程序在其他没有这个dll的电脑上运行就会出现错误(找不到这个dll)。         如果是

    2024年02月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包