美文网首页
多进程与多线程

多进程与多线程

作者: analanxingde | 来源:发表于2018-08-15 20:40 被阅读120次

关于进程与线程,之前已经分享过基本定义以及进程线程的同步和通信。本文在此基础上,介绍一些并发应用的选择优劣以及相应的实现源码

前言:为什么要并发

很多时候程序可能需要多种功能,如果只有一个主函数,就像一个快餐点的服务员,既要在前台接待客户点餐,又要接电话送外卖,没有分身术肯定会忙得你焦头烂额的。幸运的是确实有这么一种技术,让你可以分身,可以一条线在main函数里跟你的客户交流,另一条线,你早就把你外卖送到了其他客户的手里,乐哉乐哉地轻松应付一切状况,这就是多进程/线程技术。

1. 选择的根据

多进程与多线程总结
https://blog.csdn.net/lishenglong666/article/details/8557215
选择的重要基础:线程快而进程可靠性高线程有个别名叫“轻量级进程”,在有的书籍资料上介绍线程可以十倍、百倍的效率快于进程; 而进程之间不共享数据,没有锁问题,结构简单,一个进程崩溃不像线程那样影响全局,因此比较可靠。

2.简单应用例子

2.1多进程

最简单的例子,下面的代码在执行的时候:进入main函数,这就是一个进程,进程pid会打印出来,然后运行到return,该函数就退出,然后由于该函数是该进程的唯一的一次执行,所以return后,该进程也会退出

int main()
{
printf(”pid is %d/n”,getpid() );
return 0;
}

linux下fork多进程

#include <unistd.h>
#include <sys/types.h> 
#include <stdio.h>
void print_exit()
{
       printf("the exit pid:%d/n",getpid() );
} 
main () 
{ 
   pid_t pid; 
   atexit( print_exit );      //注册该进程退出时的回调函数
      pid=fork(); 
        if (pid < 0) 
                printf("error in fork!"); 
        else if (pid == 0) 
                printf("i am the child process, my process id is %d/n",getpid()); 
        else 
        {
               printf("i am the parent process, my process id is %d/n",getpid()); 
              sleep(2);
              wait();
       }
}

程序输出如下:

i am the child process, my process id is 15806
the exit pid:15806
i am the parent process, my process id is 15805
the exit pid:15805

关于fork函数,功能就是产生子进程,由于前面说过,进程就是执行的流程活动。
那么fork产生子进程的表现就是它会返回2次:一次返回0,顺序执行下面的代码。这是子进程。一次返回子进程的pid,也顺序执行下面的代码,这是父进程。(为何父进程需要获取子进程的pid呢?这个有很多原因,其中一个原因:看最后的wait,就知道父进程等待子进程的终结后,处理其task_struct结构,否则会产生僵尸进程)
额外说下atexit( print_exit ); 需要的参数肯定是函数的调用地址。所以此处print_exit 是函数指针。

2.2 多线程

线程是可执行代码的可分派单元。简而言之,线程就是把一个进程分为很多片,每一片都可以是一个独立的流程。这已经明显不同于多进程了,进程是一个拷贝的流程,而线程只是把一条河流截成很多条小溪。
先看linux提供的多线程的系统调用:

int pthread_create(pthread_t *restrict tidp,
                   const pthread_attr_t *restrict attr,
                   void *(*start_rtn)(void), 
                   void *restrict arg);
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。

多线程例子如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
 
 
void* task1(void*);
void* task2(void*);
 
 
void usr();
int p1,p2;
 
int main()
{
    usr();
    getchar();
    return 1;
}
 
 
 
void usr()
{
       pthread_t pid1, pid2;
    pthread_attr_t attr;
       void *p;
        int ret=0;
       pthread_attr_init(&attr);         //初始化线程属性结构
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   //设置attr结构为分离
       pthread_create(&pid1, &attr, task1, NULL);         //创建线程,返回线程号给pid1,线程属性设置为attr的属性,线程函数入口为task1,参数为NULL
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&pid2, &attr, task2, NULL);
//前台工作
 
ret=pthread_join(pid2, &p);         //等待pid2返回,返回值赋给p
       printf("after pthread2:ret=%d,p=%d/n", ret,(int)p);          
 
}
 
void* task1(void *arg1)
{
printf("task1/n");
//艰苦而无法预料的工作,设置为分离线程,任其自生自灭
    pthread_exit( (void *)1);
 
}
 
void* task2(void *arg2)
{
    int i=0;
    printf("thread2 begin./n");
    //继续送外卖的工作
    pthread_exit((void *)2);
}

这个多线程的例子应该很明了了,主线程做自己的事情,生成2个子线程,task1为分离,任其自生自灭,而task2还是继续送外卖,需要等待返回。(因该还记得前面说过僵尸进程吧,线程也是需要等待的。如果不想等待,就设置线程为分离线程,不等带其返回。)

3. c++11新特性atomic

C++1x除了提供传统的锁、条件变量等同步机制之外,还引入了新的atomic类型。相对于传统的mutex锁来说,atomic类型更底层,具备更好的性能,因此能用于实现诸如Lock Free等高性能并行算法。
http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/

4.面试题

多进程与多线程的区别(各自的特点)

  • 多线程:
    高效的内存共享,数据共享;较轻的上下文切换开销;创建销毁切换比较简单。
  • 多进程:
    更强的容错性,不会一阻全阻,一个进程崩溃不会整个系统崩溃。更好的多核伸缩性,进程的使用将许多内核资源(如地址空间,页表,打开的文件)隔离,在多核系统上的可伸缩性强于多线程程序
  • 多进程和多线程同样可以提高多核利用率。
    其实对于创建和销毁,上下文切换,其实在Linux系统下差别不大,Window下有较大差别。
    综上,多进程和多线程的最主要的区别就在资源共享,隔离问题。如果工作使用的内存较大,使用多线程可以避免CPU cache的换入换出,影响性能。

线程私有

  • ID,每个线程都有自己的ID作为进程中唯一的表述。
  • 一组寄存器值,用来保存状态
  • 各自的堆栈
  • 错误返回码,防止错误还未被处理就被其他线程修改。
  • 信号屏蔽码,每个线程感兴趣的信号不同。
  • 优先级

线程共享
共享的:进程的代码段,公有数据,进程打开的文件描述符,全局内存,进程的栈,堆内存等。

相关文章

  • iOS_进程与线程(多进程与多线程)

    iOS_进程与线程(多进程与多线程)

  • 多线程介绍

    一、进程与线程 进程介绍 线程介绍 线程的串行 二、多线程 多线程介绍 多线程原理 多线程的优缺点 多线程优点: ...

  • java多线程-1-并发编程

    并行与并发 并发两个队伍排一个咖啡机单cpu,多线程 并行两个队伍排两个咖啡机多cpu,多线程 进程与线程 进程间...

  • 作业2

    013-每特教育&蚂蚁课堂-第七期-从零开始学习多线程技术-多线程技术快速入门 什么是多线程 进程与线程的区别 多...

  • 107-基于多线程的ping

    多线程与多进程类似,但是每个线程没有自己的资源空间,它们共用进程的资源。多线程没有僵尸进程的问题。

  • Python并发:多线程与多进程

    本篇概要 1.线程与多线程 2.进程与多进程 3.多线程并发下载图片 4.多进程并发提高数字运算 学习Python...

  • iOS GCD详解

    多线程相关概念 1. 进程与线程 进程: 进程是程序在计算机上的一次执行活动,打开APP就开启了一个进程,它包含多...

  • 22.iOS底层学习之多线程原理

    本篇提纲:1、线程与进程2、多线程3、多线程相关面试题4、线程安全问题5、线程与runloop的关系 线程与进程 ...

  • Python(2)---并发编程

    目录 1. Python多线程与多进程知识1.1 并发与并行1.2 线程(thread)与进程(process)...

  • iOS开发之多线程(一)

    目录 概要 NSThread GCD NSOperation 多线程与锁 1.概要 进程 线程 多线程 多线程的原...

网友评论

      本文标题:多进程与多线程

      本文链接:https://www.haomeiwen.com/subject/shnwbftx.html