Linux18 ---进程和线程、线程实现方法、线程的使用接口、多线程代码实现、线程并发运行
创始人
2024-01-30 20:52:08
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。

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

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...