C/C++函数的本质以及多线程函数的调用过程

版权声明:所有的博客都是个人笔记,交流可以留言或者加QQ:2630492017 https://blog.csdn.net/qq_35976351/article/details/85295452

C/C++中,函数的本质是一段可执行代码,代码包括了局部变量、全局变量的地址等等。到汇编语言的级别,变量函数等都可以视为汇编的代码片段。函数的本质就是一个可执行代码片段的集合

线程的详细介绍:http://www.cnblogs.com/tracylee/archive/2012/10/29/2744228.html
一个线程有自己的空间,有自己的局部变量。当一个线程执行一个函数的时候,会复制函数的代码段到自己的线程空间,之后执行该代码段。对于局部变量,每个线程会保存一个局部变量的副本,因为局部变量是保存在栈内存,所以一个线程更改局部变量不会影响其他线程的局部变量。全局变量是保存在堆内存上的,因此可以理解为线程是直接操作堆内存上的全局变量,因此如果一个线程改了全局变量,那么其他线程对应的全局变量肯定会更改,因为堆内存只有一个。

在多线程编程的过程中,所谓的添加互斥量、锁和条件变量等,本质上是为了保护堆内存上的东西,或者说是全局变量。所谓的竞争条件也是指的全局的,函数内部的局部的东西,不会引起竞争!!!!!

可以这么认为,对于C++11中的std:thread来说,函数是其执行的基本单位,这里说的函数包括普通函数、函数对象、std::funtion、仿函数、lambda表达式等。执行的时候,线程会复制函数的代码片段到自己的线程空间中去执行。线程空间的本身是封闭的,也就是说一个同级别的线程不能更改另一个线程的代码片段。。我们说的线程之间的通信,本质上说的是通过全局变量的状态,使得不同线程之间可以相互通信!!!

对于类的成员函数来说,线程复制函数的时候,类的成员变量相对于线程来说也是全局!!!!

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

static int N = 0;

void fun(int n) {
  int t = 0;
  for (int i = 0; i < n; ++i) {
    ++t;
    ++N;
  }
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  std::cout << "local: " << t << std::endl;
  std::cout << "global: " << N << std::endl;
}

class C {
public:
  void fun(int n) {
    int t = 0;
    for (int i = 0; i < n; ++i) {
      ++t;
      ++_N;
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::cout << "local: " << t << std::endl;
    std::cout << "global: " << _N << std::endl;
  }

  int _N;  // 这里的_N相对于fun函数是全局的!!!!!!!
};

int main() {
  // 函数的例子
  std::cout << "function example:\n";
  std::thread t1(fun, 100000);
  std::thread t2(fun, 100000);
  t1.join();
  t2.join();
  
  std::this_thread::sleep_for(std::chrono::milliseconds(500));

  // 类的例子
  std::cout << "\nclass example:\n";
  C c;
  c._N = 0;
  std::thread t3(&C::fun, &c, 100000);
  std::thread t4(&C::fun, &c, 100000);
  t3.join();
  t4.join();

  return 0;
}

一种可能的执行结果:

function example:
local: 100000
global: 109248
local: 100000
global: 109248

class example:
local: 100000
global: 115581
local: 100000
global: 115581

猜你喜欢

转载自blog.csdn.net/qq_35976351/article/details/85295452