目录
[三、线程的设计框架 posix](#三、线程的设计框架 posix)
[2.创建多线程 pthread_create](#2.创建多线程 pthread_create)
[1.自行退出 ==》自杀 ==》子线程自己退出](#1.自行退出 ==》自杀 ==》子线程自己退出)
[2.强制退出 ==》他杀 ==》主线程结束子线程](#2.强制退出 ==》他杀 ==》主线程结束子线程)
一、基础知识
1.优点
比多进程节省资源,可以共享变量。
2.概念
1)线程是轻量级进程,一般是一个进程中的多个任务。
2)进程是系统中最小的资源分配单位。
3)线程是系统中最小的执行单位。
3.特征
3.1共享资源
3.2效率高 30%
3.3三方库: pthread clone posix
1) 编写代码头文件: pthread.h
2) 编译代码加载库: -lpthread library
gcc 1.c -lpthread
4.缺点
1)线程和进程相比,稳定性,稍微差些
2)线程的调试gdb,相对麻烦些。
info thread
二、线程与进程联系与区别
1.联系
线程属于某个进程
2.区别
1)线程比进程多了共享资源。 IPC
线程又具有部分私有资源。
进程间只有私有资源没有共享资源。
2)进程空间独立,不能直接通信。
线程可以共享空间,可以直接通信。(栈区独立)
3)当进程运行起来后,默认有一个线程。主线程
4)线程与线程,平级。主次之分
5)创建的开销不同。进程3G。线程8M栈区独立
6)稳定性。线程弱,进程强。
三、线程的设计框架 posix
1.步骤
创建多线程 --->线程空间操作 --->线程资源回收
errno strerror(errno) perror();
2.创建多线程 pthread_create
2.1头文件
#include<pthread.h>
2.2函数原型
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
2.3功能
该函数可以创建指定的一个线程。
2.4参数
thread 线程id,需要实现定义并由该函数返回。
attr 线程属性,一般是NULL,表示默认属性。
start_routine 指向指针函数的函数指针。
本质上是一个函数的名称即可。称为
th 回调函数,是线程的执行空间。
{
}
arg 回调函数的参数,即参数3的指针函数参数。
2.5返回值
成功 0
失败 错误码
2.6注意
1)一次pthread_create执行只能创建一个线程。
2)每个进程至少有一个线程称为主线程。
3)主线程退出则所有创建的子线程都退出。
4)主线程必须有子线程同时运行才算多线程程序。
5)线程id是线程的唯一标识,是CPU维护的一组数字。
6)pstree 查看系统中多线程的对应关系。
7)多个子线程可以执行同一回调函数。
8)ps -eLf 查看线程相关信息Low Weigth Process
9)ps -eLo pid,ppid,lwp,stat,comm
2.7代码示例
cpp
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *th1(void *arg)
{
while (1)
{
printf("发视频1...\n");
sleep(3);
}
return NULL;
}
void *th2(void *arg)
{
while (1)
{
printf("发视频2...\n");
sleep(2);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, th1, NULL);
pthread_create(&tid, NULL, th1, NULL);
while (1)
{
sleep(1);
}
// system("pause");
return 0;
}
2.获得线程号pthread_self
2.1函数原型
pthread_t pthread_self(void); unsigned long int; %lu
2.2功能
获取当前线程的线程id
2.3参数
无
2.4返回值
成功 返回当前线程的线程id
失败 -1;
2.5代码示例
cpp
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *th1(void *arg)
{
while (1)
{
printf("发送视频1...tid:%lu\n", pthread_self());
sleep(1);
}
return NULL;
}
void *th2(void *arg)
{
while (1)
{
printf("接受视频2...tid:%lu\n", pthread_self());
sleep(1);
}
return NULL;
}
int main(int argc, char **argv)
{
pthread_t tid1, tid2;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid2, NULL, th1, NULL);
while (1)
{
printf("main tid:%lu\n", pthread_self());
sleep(1);
}
// system("pause");
return 0;
}
四、线程的退出
1.自行退出 ==》自杀 ==》子线程自己退出
pthread_exit
整个退出
exit(1);
1.1函数原型
void pthread_exit(void *retval); exit return p;
1.2功能
子线程自行退出
1.3参数
retval 线程退出时候的返回状态,临死遗言。
1.4返回值
无
1.5代码示例
cpp
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void* th(void* arg)
{
int i = 5;
while (i--)
{
printf("th is %lu\n", pthread_self());
sleep(1);
}
pthread_exit(NULL);
// return NULL; 从功能角度描述,两者一致。建议调用pthread_exit();
}
int main(int argc, char** argv)
{
pthread_t tid;
pthread_create(&tid, NULL, th, NULL);
while (1)
{
sleep(1);
}
// system("pause");
return 0;
}
2.强制退出 ==》他杀 ==》主线程结束子线程
pthread_cancel
2.1函数原型
int pthread_cancel(pthread_t thread);
2.2功能
请求结束一个线程
2.3参数
thread 请求结束一个线程tid
2.4返回值
成功 0
失败 -1;
2.5代码示例
cpp
// #include <bits/pthreadtypes.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *th(void *arg)
{
int i = 5;
while (i--)
{
printf("tid is %lu\n", pthread_self());
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t tid;
pthread_create(&tid, NULL, th, NULL);
int i = 0;
while (1)
{
printf("main tid:%lu ,i:%d\n", pthread_self(), i);
sleep(1);
i++;
if (5 == i)
{
pthread_cancel(tid);
}
}
// system("pause");
return 0;
}
五、线程的回收
线程的回收机制 ====》不同与进程没有孤儿线程和僵尸线程。====》主线程结束任意生成的子线程都会结束。====》子线程的结束不会影响主线程的运行。
1.pthread_join
1.1函数原型
int pthread_join(pthread_t thread, void **retval);
1.2功能
通过该函数可以将指定的线程资源回收,该函数具有
阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
1.3参数
thread 要回收的子线程tid
retval 要回收的子线程返回值/状态。==》ptread_exit(值);
1.4返回值
成功 0
失败 -1;
1.5子线程的回收策略
1)如果预估子线程可以有限范围内结束则正常用pthread_join等待回收。
2)如果预估子线程可能休眠或者阻塞则等待一定时间后强制回收。
3)如果子线程已知必须长时间运行则,不再回收其资源。
1.6代码示例
cpp
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *th(void *arg)
{
int i = 5;
while (i--)
{
printf("tid is %lu\n", pthread_self());
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
//*改变指针指向的内容
//**改变指针的指向
pthread_t tid;
pthread_create(&tid, NULL, th, NULL);
pthread_join(tid, NULL);
printf("th is end\n");
// system("pause");
return 0;
}
六、线程的参数,返回值
1、传参数
传整数 ---------》int add(int a,int b); ///a b 形参
add(x,y); ////x y 实参
2.代码示例
cpp
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void* th(void*arg)
{
char* tmp = (char*)arg; //void* -> char*
strcat(arg,",world");
return arg;
}
int main(int argc, char **argv)
{
char buf[128]="hello";
pthread_t tid;
pthread_create(&tid,NULL,th,buf);// 任意类型指针到void* 不需要强转
void* ret;
pthread_join(tid,&ret);
printf("buf:%s\n",(char*)ret);
//printf("buf:%s\n",buf);
//system("pause");
return 0;
}