C语言线程库的使用
扫描二维码
随时随地手机看文章
1. 线程概述
线程是轻量级的进程(LWP:light weight process
),在 Linux 环境下线程的本质仍是进程。在计算机上运行的程序是一组指令及指令参数的组合,指令按照既定的逻辑控制计算机运行。操作系统会以进程为单位,分配系统资源,可以这样理解,进程是资源分配的最小单位,线程是操作系统调度执行的最小单位。先从概念上了解一下线程和进程之间的区别:- 进程有自己独立的地址空间,多个线程共用同一个地址空间
- 线程更加节省系统资源,效率不仅可以保持的,而且能够更高
- 在一个地址空间中多个线程独享:每个线程都有属于自己的栈区,寄存器 (内核中管理的)
- 在一个地址空间中多个线程共享:代码段,堆区,全局数据区,打开的文件 (文件描述符表) 都是线程共享的
- 线程是程序的最小执行单位,进程是操作系统中最小的资源分配单位
- 每个进程对应一个虚拟地址空间,一个进程只能抢一个 CPU 时间片
- 一个地址空间中可以划分出多个线程,在有效的资源基础上,能够抢更多的 CPU 时间片
- CPU 的调度和切换:线程的上下文切换比进程要快的多
- 线程更加廉价,启动速度更快,退出也快,对系统资源的冲击小。
- 文件 IO 操作:文件 IO 对 CPU 是使用率不高,因此可以分时复用 CPU 时间片,线程的个数 = 2 * CPU 核心数 (效率最高)
- 处理复杂的算法 (主要是 CPU 进行运算,压力大),线程的个数 = CPU 的核心数 (效率最高)
2. 创建线程
2.1 线程函数
每一个线程都有一个唯一的线程 ID,ID 类型为 pthread_t,这个 ID 是一个无符号长整形数,如果想要得到当前线程的线程 ID,可以调用如下函数:pthread_t pthread_self(void); // 返回当前线程的线程ID
在一个进程中调用线程创建函数,就可得到一个子线程,和进程不同,需要给每一个创建出的线程指定一个处理函数,否则这个线程无法工作。#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
// Compile and link with -pthread, 线程库的名字叫pthread, 全名: libpthread.so libptread.a
参数:- thread: 传出参数,是无符号长整形数,线程创建成功,会将线程 ID 写入到这个指针指向的内存中
- attr: 线程的属性,一般情况下使用默认属性即可,写 NULL
- start_routine: 函数指针,创建出的子线程的处理动作,也就是该函数在子线程中执行。
- arg: 作为实参传递到 start_routine 指针指向的函数内部
2.2 创建线程
下面是创建线程的示例代码,在创建过程中一定要保证编写的线程函数与规定的函数指针类型一致:void *(*start_routine) (void *)
:// pthread_create.c
#include
#include
#include
#include
#include
// 子线程的处理代码
void* working(void* arg)
{
printf("我是子线程, 线程ID: %ld\n", pthread_self());
for(int i=0; i<9; i)
{
printf("child == i: = %d\n", i);
}
return NULL;
}
int main()
{
// 1. 创建一个子线程
pthread_t tid;
pthread_create(