一、Linux线程介绍
1.进程与线程
进程是程序执行时的一个实例,它用来分配系统资源(CPU时间、内存等)。在面向线程设计的系统中,进程是线程的一个容器。程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行实例。
进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,尽可能选用线程。
2.使用线程的理由
理由1:线程是一种非常"节俭"的多任务操作方式。它是共享进程里面的地址空间,而多进程它是每一个进程拥有独立的地址空间来维护它的代码段、堆栈段和数据段比较耗内存,因此切换比较慢、效率比较低。
理由2:线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。
二、Linux上线程开发的主要API
多线程开发在 Linux 平台上已经有成熟的 pthread 库支持。其涉及的多线程开发的最基本概念主要包含三点:线程,互斥锁,条件。
- 线程有 3 种操作:创建,退出,等待 。
- 互斥锁有 4 种操作,创建,销毁,加锁和解锁。
- 条件有 5 种操作:创建,销毁,触发,广播和等待。
三、与线程相关的API
1.线程创建
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
返回值:若成功返回0,否则返回错误编号
参数说明:
tidp:长整型指针。
attr:线程的属性,暂可以把它设置为NULL,以创建默认属性的线程。
(*start_rtn)(void *):函数指针。
arg:给这个线程传参的参数。
新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg参数传入。
2.线程退出
单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:
- 线程只是从启动例程中返回,返回值是线程的退出码。
- 线程可以被同一进程中的其他线程取消。
- 线程调用pthread_exit:
int pthread_exit(void *rval_ptr);
参数说明:
rval_ptr:是一个无类型指针,与传给启动线程的单个参数类似。
3.线程等待
int pthread_join(pthread_t thread, void **rval_ptr)<