线程概念
- 进程
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。 - 线程
线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。
线程是一条可以执行的路径。多线程就是同时有多条执行路径在同时(并行)执行。 - 进程与线程的关系
一个程序就是一个进程,而一个程序中的多个任务则被称为线程。进程是表示资源分配的基本单位,又是调度运行的基本单位。
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。
线程正常终止的方法:
1、return从线程函数返回。
2、通过调用函数pthread_exit使线程退出
3. 线程可以被同一进程中的其他线程取消
其他变量
pthread_t tid
线程标示符 ,用于声明线程ID。
pthread_attr_t
线程属性
1)线程具有属性,用pthread_attr_t表示,在对该结构进行处理之前必须进行初始化,在使用后需要对其去除初始化。
2)调用pthread_attr_init之后,pthread_t 结构所包含的内容就是操作系统实现支持的线程所有属性的默认值。
3)如果要去除对pthread_attr_t结构的初始化,可以调pthread_attr_destroy函数。如果pthread_attr_init实现时为属性对象分配了动态内存空间,pthread_attr_destroy还会用无效的值初始化属性对象,因此如果经pthread_attr_destroy去除初始化之pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。
typedef struct
{
int detachstate; // 线程的分离状态
int schedpolicy; // 线程调度策略
structsched_param schedparam; // 线程的调度参数
int inheritsched; // 线程的继承性
int scope; // 线程的作用域
size_t guardsize; // 线程栈末尾的警戒缓冲区大小
int stackaddr_set; // 线程的栈设置
void* stackaddr; // 线程栈的位置
size_t stacksize; // 线程栈的大小
} pthread_attr_t; //线程的属性
常用函数
1.pthread_create(thread,attr,start_routine,arg)
描述:创建一个新线程并使之运行起来。该函数可以在程序的任何地方调用。
参数:
thread:指向线程标识符的指针。
attr:用来设置线程属性,上面也可以用NULL,表示使用默认的属性。
start_routine:线程将会执行一次的C函数, 是线程运行函数的起始地址。
arg: 运行函数的参数,NULL表示无参数。
示例中的函数: pthread_create(&tid,&attr,runner,argv[1]);
2.atoi(const char *str)
描述:把参数 str 所指向的字符串转换为一个整数(类型为 int 型)。
库函数:#include <stdlib.h>
实例:将字符串转换成一个整数并返d回结果。参数str 以数字开头,当函数从str 中读到非数dao字字符则结束转换并将结果返回。例如,
int i = atoi( “512.0” );
i 的值为 512.
3. pthread_attr_init(pthread_attr_t *attr)
描述:初始化一个线程属性对象
库函数:#include <pthread.h>
参数:指向一个线程属性的指针
返回值:0 - 成功,非0 - 失败
pthread_attr_init (attr);
4. pthread_attr_destroy(pthread_attr_t *attr)
描述:销毁一个线程属性对象
库函数:#include <pthread.h>
参数:指向一个线程属性的指针
返回值:0 - 成功,非0 - 失败
pthread_attr_destroy(attr);
5.pthread_join (threadid,status)
描述 :用来等待一个线程的结束,即函数的调用者在等待子线程退出后才继续执行!
参数 :
thread: 线程标识符,即线程ID,标识唯一线程。
retval: 用户定义的指针,用来存储被等待线程的返回值。
返回值 : 0代表成功。 失败,返回的则是错误号。
pthread_join(tid,NULL);
6.pthread_exit (void *retval )
描述:使用函数pthread_exit退出线程,这是线程的主动行为;
原型:void pthread_exit(void *retval)
库函数:#include <pthread.h>
参数:value_ptr是函数的返回代码
pthread_exit(0);
示例
使用Pthread机制设计线程创建实验。
#include <pthread.h>
#include <stdio.h>
int sum; /* this data is shared by the thread(s) */
void *runner(void *param); /* threads call this function */
int main(int argc, char *argv[])
{
pthread_t tid; /* the thread identifier */
pthread_attr_t attr; /* set of thread attributes */
if (argc != 2) {
fprintf(stderr,"usage: a.out <integer value>\n");
return -1;
}
if (atoi(argv[1]) < 0) {
fprintf(stderr,"%d must be >= 0\n",atoi(argv[1]));
return -1;
}
/* get the default attributes */
pthread_attr_init(&attr);
/* create the thread */
pthread_create(&tid,&attr,runner,argv[1]);
/* wait for the thread to exit */
pthread_join(tid,NULL);
printf("sum = %d\n",sum);
}
/* The thread will begin control in this function */
void *runner(void *param)
{
int i, upper = atoi(param);
sum = 0;
for (i = 1; i <= upper; i++)
sum += i;
pthread_exit(0);
}
结果
正确结果如下:
如果注释掉 **pthread_join(tid,NULL);**错误结果如下:
也就是说:子线程还没有执行完毕,main函数已经退出,那么子线程也就退出了!
注意!主函数的理解
主函数int main(int argc,char *argv[])
参数:int argc为命令行参数个数,char *argv[]为命令行参数数组。这种写法,主要用在需要从命令行获取参数的功能。
argc – 即修饰命令行参数的个数(包含argv[0])
argv[ ] – 命令行输入的字符串
argv[0] --获取可执行程序的路径
argv[i] – 自己在命令行输入的字符串
函数参数详细理解请参考:https://blog.csdn.net/yh3608/article/details/79618784