IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux系统编程:多线程编程 -> 正文阅读

[系统运维]Linux系统编程:多线程编程

1. 什么是线程

线程是比进程更小的能独立运行的基本单位,线程基本上不拥有系统资源

一个进程下可以开多个线程,这些线程是并发的

在这里插入图片描述查看线程命令

命令含义
ps -T -p -T开启线程查看
top -H -p -H开启线程查看

文件书写

文件含义
/proc/{PID}/task/线程默认的名字和进程名相同
/proc/{PID}/task/{tid}/comm线程名

2. 操作

操作函数
线程标识pthread_t pthread_self(void)
线程创建int pthread_create(pthread_t * tidp, pthread_attr_t * attr, void *(*start_rtn)(void), void * arg)
子线程终止void pthread_exit(void* retval)
线程合并int pthread_join(pthread_t tid, void **retval)
线程分离int pthread_detach(pthread_t tid)
发送信号int pthread_kill(pthread_t tid, int sig)

线程标识 pthread_self()

线程创建 pthread_create(线程id指针 , NULL, 函数指针, 函数参数)

2.1 线程的并发

创建一个线程,让主进程和这个线程并发执行:

#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;

void* handle(void*){
        for(int i=0;i<10;++i){
                sleep(1);
                cout << pthread_self() << ":" << i << endl;
        }
        return NULL;
}

int main(){
        cout << getpid() << endl;             // pid
        cout << pthread_self() << endl;       // 线程标识

        pthread_t tid;
        pthread_create(&tid,NULL,handle,NULL);     // 创建一个线程,handle传指针并返回指针,是这个线程做的事

        // 主进程也做这个
        for(int i=0;i<10;++i){
                sleep(1);
                cout << pthread_self() << ":" << i << endl;
        }
}

结果为:

[root@foundation1 C++7.13]# g++ thread.cpp -pthread
[root@foundation1 C++7.13]# ./a.out
7423
140021348697920
140021348697920:0
140021330745088:0
140021330745088140021348697920::11

140021330745088:2
140021348697920:2
140021330745088:3
140021348697920:3
140021330745088140021348697920:4:4

140021348697920140021330745088:5:5

140021348697920:6
140021330745088:6
140021348697920140021330745088:7:7

140021348697920140021330745088::8
8
140021330745088140021348697920::99

可以发现两个是并发的

在另一个窗口看所有线程ps -T -ef可以发现,两个进程id是一样的,线程id不同
在这里插入图片描述

2.2 共用变量

同一个进程中两个线程可以共用全局变量,也可以共用局部变量:

#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;

void* handle(void* p){
        int* pn = (int*)p;
        for(int i=0;i<10;++i){
                sleep(1);
                cout << pthread_self() << ":" << --*pn << endl;       // 对n减
        }
        return NULL;
}

int main(){
        cout << getpid() << endl;
        cout << pthread_self() << endl;

        int n = 5;             // 定义局部变量
        pthread_t tid;
        pthread_create(&tid,NULL,handle,&n);     // 这里需要传参

        // 主进程
        for(int i=0;i<10;++i){
                sleep(1);
                cout << pthread_self() << ":" << ++n << endl;       // 对n加
        }
}

结果为:

[root@foundation1 C++7.13]# g++ thread.cpp -pthread
[root@foundation1 C++7.13]# ./a.out
7818
139961303992128
139961303992128139961286039296::4
5
139961286039296139961303992128::45

139961286039296139961303992128::54

139961286039296139961303992128::45

139961303992128139961286039296::56

139961303992128139961286039296::56

139961286039296139961303992128::54

139961303992128139961286039296::56

139961286039296139961303992128::54

139961286039296139961303992128::54

可以发现两个线程对同一个n加减,表明变量是共用

2.3 线程合并

有时候主进程已经结束了,但子线程还没有跑完,整个程序就结束了
我们可以使用
线程合并 pthread_join( 线程id, 返回值)
让主进程等待子线程跑完

有时变量的生存周期结束后还没有完全释放,使用动态申请内存避免这种情况

#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;

void* handle(void* p){
        int* pn = (int*)p;
        for(int i=0;i<10;++i){
                sleep(1);
                cout << pthread_self() << ":" << --*pn << endl;
        }
        delete pn;                          // 到这里再释放
        // pthread_exit();
        return NULL;
}

// 创建线程
pthread_t test(){
        int* p = new int(3);         // 从这里申请,初始值为3
        pthread_t tid;
        pthread_create(&tid,NULL,handle,p);
        return tid;
}

int main(){
        cout << getpid() << endl;
        cout << pthread_self() << endl;

        pthread_t tid = test();
        int n = 5;
        // pthread_detach(tid);
        for(int i=0;i<5;++i){
                sleep(1);
                cout << pthread_self() << ":" << ++n << endl;
        }
        pthread_join(tid,NULL);                // 线程合并
        return 0;
}

结果为:

[root@foundation1 C++7.13]# g++ thread3.cpp -pthread
[root@foundation1 C++7.13]# ./a.out
11227
139954324326208
139954324326208139954306373376:2:
6
139954324326208139954306373376:7:1

139954324326208139954306373376:8:0

139954324326208139954306373376::-19

139954306373376:-2
139954324326208:10
139954306373376:-3
139954306373376:-4
139954306373376:-5
139954306373376:-6
139954306373376:-7

主进程n从5开始递增5次,线程p从3开始递减10次,但主进程会等线程完成,并且不会出现生存周期的问题

通过返回多个值的方式,使用同一个值
也可以用同一个数p,主进程p从3开始递增5次,线程p从3开始递减10次

#include <pthread.h>
#include <unistd.h>
#include <iostream>
using namespace std;

void* handle(void* p){
        int* pn = (int*)p;
        for(int i=0;i<10;++i){
                sleep(1);
                cout << pthread_self() << ":" << --*pn << endl;
        }
        delete pn;
        return NULL;
}

pair<pthread_t,int*> test(){
        int* p = new int(3);
        pthread_t tid;
        pthread_create(&tid,NULL,handle,p);
        return {tid,p};
}

int main(){
        cout << getpid() << endl;
        cout << pthread_self() << endl;

        auto [tid,p] = test();       // c++17   

        int n = 5;
        for(int i=0;i<5;++i){
                sleep(1);
                cout << pthread_self() << ":" << ++n << endl;
        }
        pthread_join(tid,NULL);
        return 0;
}

结果为:

[root@foundation1 C++7.13]# g++ thread2.cpp -pthread -std=c++17
[root@foundation1 C++7.13]# ./a.out
11325
140515561719616
140515543766784140515561719616::23

140515543766784:2
140515561719616:3
140515543766784140515561719616::23

140515543766784140515561719616::23

140515561719616140515543766784::23

140515543766784:2
140515543766784:1
140515543766784:0
140515543766784:-1
140515543766784:-2

并发过程中在2和3僵持,等待阶段开始递减

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-14 14:33:10  更:2021-08-14 14:35:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 17:02:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码