提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
Linux线程、线程创建-退出-等待、互斥锁、条件控制线程同步
提示:以下是本篇文章正文内容,下面案例可供参考
一、线程是什么?
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
一条线程指的是进程中一个单一顺序的控制流。
一个进程中可以并发多个线程,每条线程并行执行不同的任务。
1.进程与线程
- 在面向线程设计的系统中,进程本身不是基本运行单位,而是线程的容器。程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行实例。
- 进程的所有信息对该进程的所有线程都是共享的,包括可执行的程序文本、程序的全局内存和堆内存、栈以及文件描述符。
- 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
“进程——资源分配的最小单位,线程——程序执行的最小单位”
从函数调用上来说,进程创建使用fork()操作;线程创建使用clone()操作。
2.线程优势
- 线程共享进程代码段,节省空间。
- 线程通信机制方便。
二、线程API
头文件
#include<pthread.h>;
对象 | 操作 | Linux Pthread API |
---|---|---|
线程 | 创建 | pthread_create() |
线程 | 退出 | pthread_exit() |
线程 | 等待 | pthread_join() |
线程 | 获取ID | pthread_self() |
常用命令:
- ps -aux|grep a.out 查看正在运行的线程
- kill xxxxx xxxxx代表上一步显示的线程序号
1.具体API参数
1. 线程创建
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr,
void *(*start_rtn)(void *), void *restrict arg);
//tidp 指向新创建线程的线程ID;
//attr 定制线程属性,暂可以把它设置为NULL,以创建默认属性的线程。
//start_rtn 使用start_rtn函数指针,指向所需要操作的函数。
//arg 利用arg参数给该线程传参。
2. 线程退出
单个线程可以通过以下三种方式退出,在不终止整个进程的情况下停止它的控制流:
1)线程只是从启动例程中返回,返回值是线程的退出码。
2)线程可以被同一进程中的其他线程取消。
3)线程调用pthread_exit。
#include <pthread.h>
int pthread_exit(void *rval_ptr);
//进程中的其他线程可以通过调用pthread_join函数访问到这个指针。
3. 线程等待
调用这个函数的线程将一直阻塞,直到指定的线程调用pthread_exit、从启动例程中返回或者被取消。
#include <pthread.h>
int pthread_join(pthread_t thread, void **rval_ptr);
// 返回:若成功返回0,否则返回错误编号
//rval_ptr是个二级指针
4. 线程脱离
pthread_detach函数把指定的线程转变为脱离状态。一般使用频率较少。
#include <pthread.h>
int pthread_detach(pthread_t thread);
// 返回:若成功返回0,否则返回错误编号
本函数通常由想让自己脱离的线程使用,就如以下语句:
pthread_detach(pthread_self());
5. 线程ID获取及比较
#include <pthread.h>
pthread_t pthread_self(void);
// 返回:调用线程的ID
对于线程ID比较,为了可移植操作,我们不能简单地把线程ID当作整数来处理,
因为不同系统对线程ID的定义可能不一样。我们应该要用下边的函数:
#include <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2);
// 返回:若相等则返回非0值,否则返回0
6.线程例子
#include <stdio.h>
#include <pthread.h>
// int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
// void *(*start_routine) (void *), void *arg);
void *funcl1(void *arg) //pthread_create所需调用函数
{
static int ret =10;
printf("t1: %ld,thread is create\n ",(unsigned long)pthread_self());//进程ID获取
printf("t1: the param is %d\n",*