实操(多线程特点、健壮性降低、缺乏访问控制)Linux

发布于:2025-04-07 ⋅ 阅读:(28) ⋅ 点赞:(0)

线程

创建两个线程

makefile(添加原生线程库)

mythread:thread.cc
	g++ -o $@ $^ -std=c++11 -lpthread 
.PHONY:clean
clean:
	rm -f mythread

thread.cc

#include <iostream>
#include <pthread.h>
#include<unistd.h>

using namespace std;

void *threadRun1(void *args)
{
    while(true)
    {
        sleep(1);
        cout << "t1 thread..." << getpid() << endl;
    }
}

void *threadRun2(void *args)
{
    while(true)
    {
        sleep(1);
        cout << "t2 thread..." << getpid() << endl;
    }
}


int main()
{
    pthread_t t1, t2, t3;
    // 取t地址,线程属性,线程执行的函数,后面说
    pthread_create(&t1, nullptr, threadRun1, nullptr);
    pthread_create(&t2, nullptr, threadRun2, nullptr);

    while(true)
    {
        sleep(1);
        cout << "main thread..." << getpid() << endl;
    }
}

 1 健壮性降低(多线程的特点)

  • 有一个线程出问题,导致整个进程全部出问题

thread.cc

void *threadRun2(void *args)
{
    char *s = "hello";
    while(true)
    {
        sleep(1);
        cout << "t2 thread..." << getpid() << endl;
        *s = 'H'; //修改常量,让这个线程奔溃
    }
}

显示(发生段错误导致整个进程崩溃) 

  • 系统角度:线程是进程的执行分支,线程干了,就是进程干了
  • 信号角度:页表转换的时候,MMU识别写入权限的时候,没有验证通过,MMU发生异常问题,就被操作系统识别,因为信号是已进程为主的,他就要给进程发信号,向每个进程都写了异常,最后每个pcb都会被终止,操作系统就把进程整体全干掉了

2 缺乏访问控制(多线程的特点)

虚拟地址经过页表映射,你自己的代码和数据,包括操作系统的系统调用接口,系统的代码,各种数据全部在内存里放着,你要找到物理内存就必须要经过虚拟地址转化,那就尴尬了,因为执行流看到的资源都是通过地址空间看到的,多个LWP看到的是同一个地址空间,所以所有的线程可能会共享进程的大部分资源,因为地址空间是一样的,页表是一样的,把代码分了,但是未来写一个函数会被所有线程访问,定义一个全局变量,多个线程可能都会访问到,下面验证一下

thread.cc(定义一个全局变量,线程1和主线程负责打印,线程2负责修改)

int g_val = 0; //全局变量,在多线程场景中,多个线程看到的是同一个变量

void *threadRun1(void *args)
{
    while(true)
    {
        sleep(1);
        cout << "t1 thread..." << getpid() << "g_val: " << &g_val <<  endl;
    }
}

void *threadRun2(void *args)
{
    //char *s = "hello";
    while(true)
    {
        sleep(1);
        cout << "t2 thread..." << getpid() << "g_val: " << &g_val++ << endl;
        //*s = 'H'; //修改常量,让这个线程奔溃
    }
}


int main()
{
    pthread_t t1, t2, t3;
    // 取t地址,线程属性,线程执行的函数,后面说
    pthread_create(&t1, nullptr, threadRun1, nullptr);
    pthread_create(&t2, nullptr, threadRun2, nullptr);

    while(true)
    {
        sleep(1);
        cout << "main thread..." << getpid() << "g_val: " << &g_val << endl;
    }
}
  • 一个发生改变会影响整体

注:这个多线程在并发访问的时候是有问题的,我们以后再来谈