一、线程的概念
线程是进程内部的一条执行序列或执行路径,一个进程可以包含多条线程。
一个进程中有两条或多条执行路径的时候,它们是可以同时执行的,也就是说,一个进程中的多个线程是可以同时执行的。当我们需要一个程序同时执行两个不同操作的时候就引入了多线程。如果是一个单线程,只有一条路径时,不可能同时执行两个不同操作,因为其中一个操作正在执行的时候,另一个操作是阻塞状态。
当一个进程有一个主线程和一个子线程的时候,主线程和子线程可以同时执行;也可以有多个相同的子线程,这样就是一个主线程和多个子线程同时执行,多个子线程做的事情是一样的;也可以有多个不同的子线程,这样就是一个主线程和多个不同的子线程同时执行,多个子线程做的事情不一样。
二、线程的实现方式
在操作系统中,线程的实现有以下三种方式:
1.内核级线程
2.用户级线程
3.组合级线程
Linux 中线程的实现:
Linux 实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux把所有的线程都当做进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有唯
一隶属于自己的task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)。
三、进程与线程的区别
1.进程:一个正在运行的程序
进程是资源分配的最小单位;
进程有自己的独立地址空间;
进程的创建消耗资源大;
进程的切换开销大。
2.线程:是进程内部的一条执行序列或执行路径
线程是CPU调度的最小单位;
线程共享进程中的地址空间;
线程的创建相对较小;
线程的切换开销相对较小。
四、一个简单的多线程程序
1.创建线程的函数pthread_create:
使用pthread_create函数需要引用头文件pthread.h。由于pthread_create在线程库中,所以在编译程序的时候要链接pthread。
参数解释:
第一个参数thread:事先创建好的pthread_t类型的参数。成功时thread指向的内存单元被设置为新创建线程的线程ID。
第二个参数attr:用于定制各种不同的线程属性。通常直接设为NULL。
第三个参数start_routine:新创建线程从此函数开始运行。
第四个参数arg:start_routine函数的参数。无参数时设为NULL即可。有参数时输入参数的地址。当多于一个参数时应当使用结构体传入。
返回值:成功返回0,否则返回错误码。
2.编写一个简单的多线程程序
代码如下:
运行结果:
出现这样的运行结果是因为主函数直接就运行完了,直接5次循环就结束了,线程函数还没有来得及输出,因为主函数退出之后系统会自动调用exit来退出整个进程,相当于直接把当前进程结束了,不管有多少条执行路径都随之退出了。
由于以上代码的执行结果并不理想,主线程和子线程好像并没有同时运行,修改以上代码,如下图所示:
在主线程和子线程每次输出数据之后都睡眠1秒,这时就可以看到,两个进程是同时执行的,至于执行的顺序没有固定顺序,运行结果如下图:
pthread_join 方法
这个方法是当主线程执行完之后不退出进程,而是等待子线程执行,等子线程执行完之后系统才会调用exit来退出进程。
将代码修改如下:
运行结果如下:
由结果可以看出,主线程和子线程同时执行。