理解线程的相关概念

简介: 理解当操作系统引入线程的概念后,进程是操作系统独立分配资源的单位,线程成为系统调度的单位,也是系统并发运行的独立单位。同一个进程中的各个线程共享进程的地址空间。

1.编写一个程序,在其main()函数中创建一个(或多个)线程,观察该线程是如何与主线程并发运行的。输出每次操作后的结果;
2.在main()函数外定义一个变量int shared(全局变量),在main()中创建一个线程,在main()中和新线程shared进行循环加/减操作,观察该变量的变化;
3.修改程序把int shared变量定义到main()函数之内,重复第(2)步操作,观察该变量的变化。
编写一个程序,在其main()函数中创建至少两个线程,在这些线程中分别说明(定义)名称相同的整型变量(例如,int x;),分别在各个线程中修改这些变量,试观察这些变量值的变化。

1.流程图
1.1 编写一个程序,在其main()函数中创建一个(或多个)线程,观察该线程是如何与主线程并发运行的。输出每次操作后的结果;
image.png
1.2.在main()函数外定义一个变量int shared(全局变量),在main()中创建一个线程,在main()中和新线程shared进行循环加/减操作,观察该变量的变化;
image.png
1.3.修改程序把int shared变量定义到main()函数之内,重复第(2)步操作,观察该变量的变化。

1.4.编写一个程序,在其main()函数中创建至少两个线程,在这些线程中分别说明(定义)名称相同的整型变量(例如,int x;),分别在各个线程中修改这些变量,试观察这些变量值的变化。
2.代码
编写一个程序,在其main()函数中创建一个(或多个)线程,观察该线程是如何与主线程并发运行的。输出每次操作后的结果;

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

using namespace std;

#define NUM_THREADS 2

void *child_thread(void*args){
    for(int i=0;i<5;i++){
        cout<<"this is a child thread, thread id is: "<<pthread_self()<<endl;
    }
    return NULL;
}

int main(){
    pthread_t tids[NUM_THREADS];
    for(int i=0;i<NUM_THREADS;i++){
        int ret=pthread_create(&tids[i],NULL,child_thread,NULL);
        if(ret!=0){
            cout<<"pthread create error! error code is: "<<ret<<endl;
        }
    }
    cout<<"this is a main thread, thread id is: "<<pthread_self()<<endl;
    pthread_exit(NULL);
}

2.2.在main()函数外定义一个变量int shared(全局变量),在main()中创建一个线程,在main()中和新线程shared进行循环加/减操作,观察该变量的变化;

include

include

include <unistd.h>

include <pthread.h>

using namespace std;

define NUM_THREADS 1

int shared = 0;
// 线程的运行函数
void child_thread(void args)
{

for (int i = 0; i < 5; i++)
{
    // cout<<"this is a child thread, thread id is: "<<pthread_self()<<endl;
    cout << "new thread" << --shared << endl;
}
return NULL;

}

int main()
{

// 存储进程的id
pthread_t tids[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++)
{
    // 创建一个进程,参数分为是
    int ret = pthread_create(&tids[i], NULL, child_thread, NULL);
    if (ret != 0)
    {
        cout << "pthread create error! error code is: " << ret << endl;
    }
}
cout << "this is a main thread, thread id is: " << pthread_self() << endl;
for (int i = 0; i < 5; i++){
    cout << "main thread" << ++shared << endl;
}
pthread_exit(NULL);

}
2.3.修改程序把int shared变量定义到main()函数之内,重复第(2)步操作,观察该变量的变化。

include

include

include <unistd.h>

include <pthread.h>

include

using namespace std;

define NUM_THREADS 1

// 线程的运行函数
void child_thread(int &shared)
{

// static mutex mtex;
for (int i = 0; i < 5; i++)
{
    // cout<<"this is a child thread, thread id is: "<<pthread_self()<<endl;
    cout << "new thread" << --shared << endl;
}

}

int main()
{

int shared = 0;
thread thread1(child_thread,ref(shared));// 创建这个线程
// 主函数中调用这个函数
child_thread(shared);
thread1.join();
for (int i = 0; i < 5; i++)
{
    cout << "main thread" << ++shared << endl;
}
pthread_exit(NULL);

}
2.4.编写一个程序,在其main()函数中创建至少两个线程,在这些线程中分别说明(定义)名称相同的整型变量(例如,int x;),分别在各个线程中修改这些变量,试观察这些变量值的变化。

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

using namespace std;

#define NUM_THREADS 1

void process1(){
    int x=10;
    cout<<"this is the first process, x is: "<<x<<endl;
    for(int i=0;i<10;i++){
        cout << "this is the first process, xx is: " << --x << endl;
    }
    sleep(1);
}
void process2()
{
    int x = 20;
    cout << "this is the second process, x is: " << x << endl;
    for (int i = 0; i < 10; i++)
    {
        cout << "this is the second process, xx is: " << --x << endl;
    }
    sleep(1);
}
void process3()
{
    int x = 30;
    cout << "this is the thread process, x is: " << x << endl;
    for (int i = 0; i < 10; i++)
    {
        cout << "this is the second process, xx is: " << --x << endl;
    }
    sleep(1);
}
int main()
{
    thread thread1(process1);
    thread thread2(process2);
    thread thread3(process3);
    thread1.join();
    thread2.join();
    thread3.join();
    // pthread_exit(NULL);
    return 0;
}

编写一个程序,在其main()函数中创建一个(或多个)线程,观察该线程是如何与主线程并发运行的。输出每次操作后的结果;
image.png

我们看到,子线程和主线程处在一种交替执行的状态,也就是说,子线程和主线程要么是并发实行的,要么是并行执行的,打印是并发执行的。
在main()函数外定义一个变量int shared(全局变量),在main()中创建一个线程,在main()中和新线程shared进行循环加/减操作,观察该变量的变化;
image.png

可以看到,主线程和生成的线程共用的是一个变量,也就是一个进程的线程之间共享的是一个相同的参数空间。
修改程序把int shared变量定义到main()函数之内,重复第(2)步操作,观察该变量的变化。
image.png

放到了函数之内,由于进行了参数的传递,使用的依然是同一个地址空间的变量,相同的变量。
编写一个程序,在其main()函数中创建至少两个线程,在这些线程中分别说明(定义)名称相同的整型变量(例如,int x;),分别在各个线程中修改这些变量,试观察这些变量值的变化。
image.png

线程之内使用的是局部变量,是自己线程单独享有的变量,由此我们可以知道,线程可以有自己单独享有的变量。

思考:分析进程和线程的不同之处。
1.线程和进程的不同之处。
因为线程为轻量级进程,所以线程与进程的主要不同之处为:线程没有自己的地址空间(adress space)。
如果进程创建多个线程,所有的线程都将包含在它的地址空间中。这就是为什么它们如此容易共享资源,以及为什么可以访问进程内存的原因。
进程有自己的地址空间。子进程只有数据片段的拷贝。对变量的修改不会影响父进程的数据。为了让父进程和子进程共享内存,必须创建一个共享内存区域。父和子进程必须使用进程间通信机制(如管道)在两者间通信和传递数据。
通过读取和写入进程变量,统一进程的线程可以传递和使用它们处理的数据。
对其他进程的控制限制于父—子关系。子进程对两者之间无控制。进程内的线程被看作同位体,而且处于相等的级别。不管是哪一个线程创建可哪一个线程,进程内的任何线程可以销毁、挂起、恢复或更改其他线程的优先权。线程也要对整个进程施加控制。进程内的任何线程可以通过销毁主线程来销毁该进程。
销毁主线程将导致该进程的所有线程销毁。对主线程的修改可能影响进程的所有线 程。对进程优先权的更改将改变进程内继承了优先权但没有作修改的所有线程的优 先权。

目录
相关文章
|
2月前
|
Go 调度 开发者
[go 面试] 深入理解进程、线程和协程的概念及区别
[go 面试] 深入理解进程、线程和协程的概念及区别
|
4月前
|
分布式计算 JavaScript 前端开发
多线程、多进程、协程的概念、区别与联系
多线程、多进程、协程的概念、区别与联系
64 1
|
4月前
|
分布式计算 并行计算 安全
在Python Web开发中,Python的全局解释器锁(Global Interpreter Lock,简称GIL)是一个核心概念,它直接影响了Python程序在多线程环境下的执行效率和性能表现
【6月更文挑战第30天】Python的GIL是CPython中的全局锁,限制了多线程并行执行,尤其是在多核CPU上。GIL确保同一时间仅有一个线程执行Python字节码,导致CPU密集型任务时多线程无法充分利用多核,反而可能因上下文切换降低性能。然而,I/O密集型任务仍能受益于线程交替执行。为利用多核,开发者常选择多进程、异步IO或使用不受GIL限制的Python实现。在Web开发中,理解GIL对于优化并发性能至关重要。
56 0
|
5月前
|
Java
Java中的多线程编程:概念、实现与挑战
【5月更文挑战第30天】本文深入探讨了Java中的多线程编程,涵盖了多线程的基本概念、实现方法以及面临的挑战。通过对Java多线程编程的全面解析,帮助读者更好地理解多线程在Java中的应用,提高程序的性能和效率。
|
11天前
|
数据采集 消息中间件 并行计算
进程、线程与协程:并发执行的三种重要概念与应用
进程、线程与协程:并发执行的三种重要概念与应用
27 0
|
2月前
|
缓存 前端开发 JavaScript
一篇文章助你搞懂java中的线程概念!纯干货,快收藏!
【8月更文挑战第11天】一篇文章助你搞懂java中的线程概念!纯干货,快收藏!
31 0
一篇文章助你搞懂java中的线程概念!纯干货,快收藏!
|
3月前
|
Java 程序员 调度
Java中的多线程编程:概念、实现及性能优化
【5月更文挑战第85天】本文主要探讨了Java中的多线程编程,包括其基本概念、实现方式以及如何进行性能优化。首先,我们将介绍多线程的基本概念,然后详细讨论如何在Java中实现多线程,包括继承Thread类和实现Runnable接口两种方式。最后,我们将探讨一些提高多线程程序性能的策略,如使用线程池和减少同步开销等。
|
3月前
|
监控 Java 调度
Java面试题:描述Java线程池的概念、用途及常见的线程池类型。介绍一下Java中的线程池有哪些优缺点
Java面试题:描述Java线程池的概念、用途及常见的线程池类型。介绍一下Java中的线程池有哪些优缺点
56 1
|
3月前
|
缓存 Linux 编译器
【Linux】多线程——线程概念|进程VS线程|线程控制(下)
【Linux】多线程——线程概念|进程VS线程|线程控制(下)
59 0
|
3月前
|
存储 Linux 调度
【Linux】多线程——线程概念|进程VS线程|线程控制(上)
【Linux】多线程——线程概念|进程VS线程|线程控制(上)
61 0