一:线程的基本知识
首先我们应该知道线程是在进程内部运行的,所谓的内部运行是在地址空间内运行;线程是进程的一个分支,但是没有专门的结构体来描述线程,所以没有真正意义上的线程,他的实现是通过进程来模拟实现(以共享地址空间来模拟)。
Linux下识别到的PCB都可以看作是轻量级进程。进程承担分配基本资源的基本实体,具有独立性;线程是CPU调度的基本单位,线程会产生各种临时变量保存到栈当中,每个线程都有自己的私有线程结构,每个线程都有自己的上下文。
由于同一个进程的多个线程共享同一地址空间,因此Text Segment·Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都是可以访问到的,除此之外,各线程还共享以下进程资源和环境:
1,文件描述表
2,每个信号的处理方式(SIG_IGN·SIG_DFL或者自定义的信号处理函数)
3,当前工作目录
但是有些资源是每个线程个有一份:
1,线程id
2,上下文,包括各种寄存器的值,程序计数器和栈指针
3,栈空间
4,errno变量
5,信号屏蔽字
6,调度优先级
二:线程控制
线程的创建:
我们先了解创建一个线程的函数是:pthread_create,它的函数原型为:
我们编写创建线程的代码时一定要注意:在编写Makefile,gcc时一定要注意加上-lpthread。那我们编写的线程创建程序为:
#include<stdio.h>
2 #include<pthread.h>
3 void* thread_run(void *arg)
4 {
5 while(1)
6 {
7 printf("new pthread,thread is:%u,pid is:%d\n",pthread_self(),getpid());
8 sleep(1);
9 }
10 }
11 int main()
12 {
13 pthread_t tid;
14 pthread_create(&tid,NULL,thread_run,NULL);
15 while(1)
16 {
17 printf("main pthread,thread is:%u,pid:%d\n",pthread_self(),getpid());
18 sleep(3);
19 }
20 return 0;
21 }
运行结果是:
线程的等待:
线程等待的函数原型为:
线程等待的程序为:
1 #include<stdio.h>
2 #include<pthread.h>
3 void* thread_run(void *arg)
4 {
5 sleep(3);
6
7 printf("new pthread,thread is:%u,pid is:%d\n",pthread_self(),getpid());
8 return (void *)1;
9
10 }
11 int main()
12 {
13 pthread_t tid;
14 pthread_create(&tid,NULL,thread_run,NULL);
15 void *ret;
16 pthread_join(tid,&ret)
17 printf("join new success,ret:%d\n",(int)ret);
18 return 0;
19 }
运行结果为:
线程的终止:
1,从线程函数内部return可以终止这个线程,注意如果是main函数终止,那么整个线程终止
2,调用pthread_exit()函数,或者函数pthread_cancel(),终止同一进程中的另一个线程。
线程终止的函数原型为:
线程终止的代码:
1 #include<stdio.h>
2 #include<pthread.h>
3 void* thread_run(void *val)
4 {
5 printf("new pthread,thread is:%u,pid is:%d\n",pthread_self(),getpid());
6 pthread_exit((void*)123);
7
8 }
9 int main()
10 {
11 pthread_t tid;
12 if(pthread_create(&tid,NULL,thread_run,NULL)!=0);
13 {
14 printf("creat thread error!\n");
15 return 0;
16 }
17 pthread_cancel(tid);
18 void *ret;
19 pthread_join(tid,&ret);
20 printf("join new success,ret:%d\n",(int)ret);
21 return 0;
22 }
其运行结果: