Linux18 ---进程和线程、线程实现方法、线程的使用接口、多线程代码实现、线程并发运行
创始人
2024-01-30 20:28:15
0

一、进程和线程:

1、进程和线程的相关概念:

进程:是一个正在运行的程序,是个动态的概念。一个进程可以实现多个线程。

线程:是进程内部的一条执行路径或称为执行序列,不同平台下线程的实现机制不相同,但都被称为线程。
在这里插入图片描述

在这里插入图片描述

2、进程和线程的区别:

进程是资源分配的最小单位,线程是CPU 调度的最小单位。
进程有自己的独立地址空间,线程共享进程中的地址空间。
进程的创建消耗资源大,线程的创建相对较小。
进程的切换开销大,线程的切换开销相对较小。

二、线程实现方法

在操作系统中,线程的实现有以下三种方式:

用户级线程:开销小,但无法使用多个处理器;
内核级线程:相对来讲开销大,可以利用多个处理器;
组合级模型

在这里插入图片描述

Linux中线程的实现:

Linux实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux把所有的线程都当做进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有唯一隶属于自己的 task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)。

三、线程的使用

1、头文件

#include 

编译时需要带上 -lpthread
在这里插入图片描述

2、创建线程 --pthread_create

int pthread_create(pthread_t *thread, const pthread_attr_t*attr,void*(*start_routine)(void *), void *arg);
pthread_create() :用于创建线程
thread :接收创建的线程的
IDattr :指定线程的属性
start_routine :指定线程函数
arg :给线程函数传递的参数,成功返回0,失败返回错误码

3、退出线程–pthread_exit

int pthread_exit(void *retval);
pthread_exit() :退出线程。
retval :指定退出信息。

4、等待线程结束/合并线程–pthread_join()

int pthread_join(pthread_t thread, void**retval);
pthread_join() :等待thread指定的线程退出,线程未退出时,该方法阻塞;
retval :接收thread 线程退出时,指定的退出信息

四、多线程代码实现

#include 
#include 
#include 
#include 
#include #include //线程函数fun
void* pthread_fun(void* arg)
{int i = 0;for(;i < 5;++i){sleep(1);printf("fun thread running\n");}//退出线程pthread_exit("fun over");
}int main()
{//创建线程idpthread_t id;//该地址由pthread_create创建,其创建后会自动写入,不需要自己定义//创建线程//pthread_create(&id,NULL,pthread_fun,NULL);int res = pthread_create(&id,NULL,pthread_fun,NULL);//创建了fun线程函数assert(res == 0);int i = 0;for(; i < 5; i++){sleep(1);printf("main thread running\n");}//等待thread指定的线程退出,线程未退出时,该方法阻塞;char *s = NULL;pthread_join(id,(void **)&s);//将二级指针强转成void类型的printf("s = %s\n",s);exit(0);
}

运行结果:
在这里插入图片描述

不加sleep,难以观察到并发运行的发生:
在这里插入图片描述

五、线程并发运行(不加同步)

1、并发和并行

并发和并行(并行需要多个处理器,但多个处理器不一定是并行运行,因为要共享资源):
在这里插入图片描述

2、一次创建5个线程,让每个线程打印自己是第几个被创建的。

#include 
#include 
#include 
#include 
#include 
#include void* thread_fun(void* arg)
{int index = *((int *)arg);int i = 0;printf("index = %d\n",index);sleep(1);
}int main()
{//创建五个线程pthread_t id[5];int i = 0;for(; i < 5 ; i++){pthread_create(&id[i],NULL,thread_fun,(void*)&i);}for( i = 0; i < 5 ; i++){pthread_join(id[i],NULL);}exit(0);
}

运行结果:
发现输出的值每次运行都太不一样。
这里输出的index 是其运行输出函数时,那一刻所获取的 i 的值。而i的值该程序有三个函数再使用 i。而这个循环的执行速度非常快,所以获取i的值就会出错。
后面的0,较大概率是最后一个for循环的0。因为这里有pthread_join() (等待thread指定的线程退出,线程未退出时,该方法阻塞)。

在这里插入图片描述

#include 
#include 
#include 
#include 
#include 
#include void* thread_fun(void* arg)
{int index = *((int *)arg);int i = 0;for(; i < 5; i++){printf("index = %d\n",index);sleep(1);}
}int main()
{//创建五个线程pthread_t id[5];int i = 0;for(; i < 5 ; i++){pthread_create(&id[i],NULL,thread_fun,(void*)&i);}for( i = 0; i < 5 ; i++){pthread_join(id[i],NULL);}exit(0);
}

在这里插入图片描述
在这里插入图片描述

3、创建5个线程,同时对一个全局变量进行++,加到5000

测试代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include int g = 0;void* thread_fun(void* arg)
{int i = 0;for(; i < 1000; i++){printf("g = %d\n",++g);}
}int main()
{pthread_t id[5];int i = 0;for(; i < 5; i++){pthread_create(&id[i],NULL,thread_fun,NULL);}for( i = 0; i < 5; i++){pthread_join(id[i],NULL);}exit(0);
}

运行结果:

多处理器测试:

发现最终所得值小于等于5000;

在这里插入图片描述
在这里插入图片描述

单处理器测试:

在这里插入图片描述

结果都为5000

在这里插入图片描述在这里插入图片描述

对于main.c ,计算机不能直接执行,编译好生成的main.exe/main ,程序由一条条指令构成,内部指令的排序格式:ELF(linux)、PE(Windows)。所以对于一个a+b运行时,最终最终转换成指令会是多条指令。而我们要将内存中的一个值进行++操作时,需要将其读到cpu里,由cpu内部的加法器进行++操作后,再写回内存。所以对于上面的代码,对g进行++的时候,对于多个并行线程对其++,就有可能在一个线程进行++的过程中,还没完成时,另一个线程错误获取了g,导致两个对其同时进行++,只+1;而循环次数却+2。所以回小于5000。

在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

美国童星被刺身亡,曾出演《狮子...   中新网12月28日电 据美国有线电视新闻网(CNN)27日报道,曾在百老汇迪士尼音乐剧《狮子王》...
锚定育人根本 书写时代答卷(深...   2025年,是教育部党组确定的“实干年”。教育画卷,在时代浪潮中铺展。  立德树人事业汇聚更加广...
数览中国脉动|科技赋能!“汗水...   农业机械化、智能化,是农业现代化的重要支撑。  当前,我国正加快发展农业新质生产力,以科技赋能粮...
覆盖生育、养育、教育 国家正加...   衡量一个国家经济社会发展的成果,很大程度上,取决于对社会福利制度的构建。其中,对一个家庭来说,围...
香港由治及兴迈出新步伐 勇于担...   从《维护国家安全条例》两部附属法例刊宪生效,到携手广东、澳门成功举办十五运会和残特奥会,再到成功...
全国规模以上工业企业利润累计增...   国家统计局今天(12月27日)发布的数据显示,1—11月份,全国规模以上工业企业实现利润总额66...
缅甸举行大选第一阶段投票   当地时间12月28日6时起,缅甸仰光、内比都、曼德勒等多个省邦102个乡镇开始陆续举行全国多党民...
湖北潜江警方:一男子醉酒持玩具...   央视网消息:据潜江公安微信公众号消息,湖北潜江市公安局12月27日发布警情通报,12月26日21...
“涨到可怕了!”有人一觉醒来赚... 新闻荐读 白银暴涨10%,接近20元/克;现货黄金站上4549美元/盎司,刷新历史高位;铂金大涨,铂...
视频丨日本民众举行集会 反对重...   26日晚,部分日本民众在日本首相官邸前举行抗议集会。他们表示,在日本核设施老化、管理混乱、监管不...