1. 线程
1.1 定义
线程是一个轻量级的进程
是一个任务被创建、调度、消亡的过程
1.2 线程与进程的关联
线程是CPU任务调度的最小单元
进程是操作系统资源分配的最小单元
线程位于进程空间内部,多线程只需在同一进程空间切换调度任务
2 线程的创建
2.1 进程的创建:文本段、数据段、系统数据段、内核
2.2 线程的创建:栈区独立,其余区域与进程共享
2.3 进程中的所有线程
独享:栈区——局部变量、
共享:文本段、数据段、堆区——全局变量/静态变量/字符串常量/malloc空间/代码
3. 线程的调度
宏观并行、微观串行
4. 线程消亡
与进程消亡机制相同
5. 进程和线程的区别
1.进程是操作系统资源分配的最小单元
2.线程是CPU任务调度的最小单元
6. 多进程和多线程的优缺点
1.执行效率:
多线程 > 多进程
1.多线程只需在同一进程空间内部切换调度任务
2.多进程需要在不同进程空间来回切换调度任务
2.安全
多进程 > 多线程
1.多进程各自独立,一个进程异常结束,不会影响其余进程
2.多线程都在同一进程空间内部,一个线程异常结束,导致进程异常结束,
进程中其余所有线程均会结束
3.通信能力:
多线程 > 多进程
1.多线程可以利用共享空间实现任务通信
2.多进程没有共享空间,所以通信方式比较复杂
4.通信安全性:
多进程 > 多线程
1.多进程没有共享空间,依赖第三方对象完成通信,中间不涉及资源竞争问题
2.多线程有共享空间,多个任务通信会产生资源竞争,需要加锁
7. 线程相关函数接口
对标进程函数接口
1.fork pthread_create
2.exit pthread_exit
3.wait pthread_join
4.getpid pthread_self
7. 1. pthread_create
1. 定义
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
2. 功能
在一个进程中创建一个线程
3. 参数
thread:存放线程ID空间首地址
attr:线程属性空间首地址 默认属性NULL
start_routine:线程入口函数
arg:线程函数的传参
4. 返回值
成功返回0
失败返回错误码
5. 示例程序
5.1 创建
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *th1(void *arg)
{
while(1)
{
printf("发送视频\n");
sleep(1);
}
return NULL;
}
void *th2(void *arg)
{
while(1)
{
printf("接受控制\n");
sleep(1);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,th1,NULL);
pthread_create(&tid2,NULL,th2,NULL);
while(1)
{
sleep(1);
}
return 0;
}
5.2 对回调函数的操作
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
typedef struct
{
char buf[50];
int num ;
}ARG;
void * th1(void *arg)
{
ARG * tmp = (ARG* )arg;
strcpy(tmp->buf,"hello");
tmp->num = 20;
return tmp;
}
int main(int argc, char *argv[])
{
pthread_t tid1;
ARG arg;
pthread_create(&tid1, NULL, th1, &arg);
void* ret;
pthread_join(tid1,&ret);
printf("ret buf:%s num:%d\n", ((ARG*)ret)->buf , ((ARG*)ret)->num);
return 0;
}
7.2. pthread_self
1. 定义
pthread_t pthread_self(void);
2. 功能
获取当前线程的线程id
3. 参数
无
4. 返回值
成功 返回当前线程的线程id
失败 -1
5. 示例程序
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *th1(void *arg)
{
while(1)
{
printf("发送视频 th1, tid:%lu\n", pthread_self());
sleep(1);
}
return NULL;
}
void *th2(void *arg)
{
while(1)
{
printf("接受控制 th2, tid:%lu\n", pthread_self());
sleep(1);
}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid1,
pthread_t tid2;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid2, NULL, th2, NULL);
printf("main tid1:%lu, tid2:%lu\n", tid1, tid2);
while(1)
{
printf("main th tid %lu\n", pthread_self());
sleep(1);
}
return 0;
}
7.3.pthread_exit
1. 定义
void pthread_exit(void *retval);
2. 功能
子线程自行退出
3. 参数
retval 线程退出时候的返回状态,临死遗言
4. 返回值
无
5. 示例程序
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *th1(void *arg)
{
while(1)
{
printf("发送视频\n");
sleep(1);
}
pthread_exit(NULL);
}
void *th2(void *arg)
{
while(1)
{
printf("接受控制\n");
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t tid1;
pthread_t tid2;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid2, NULL, th2, NULL);
while(1)
{
sleep(1);
}
return 0;
}
7.4.pthread_cancel
1. 定义
int pthread_cancel(pthread_t thread);
2. 功能
请求结束一个线程(强制退出、他杀、 主线程结束子线程)
3. 参数
thread 请求结束一个线程tid
4. 返回值
成功 0
失败 -1
5. 示例程序
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void * th1(void *arg)
{
while(1)
{
printf("发送视频\n");
sleep(1);
}
pthread_exit(NULL);
}
void * th2(void *arg)
{
while(1)
{
printf("接受控制\n");
sleep(1);
}
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t tid1;
pthread_t tid2;
pthread_create(&tid1, NULL, th1, NULL);
pthread_create(&tid2, NULL, th2, NULL);
int i = 0 ;
while(1)
{
i++;
if(3 == i)
{
pthread_cancel(tid1);
}
if(5 == i)
{
pthread_cancel(tid2);
}
if(6 == i)
{
pthread_exit(NULL);
}
sleep(1);
}
return 0;
}
7.5. pthread_join
1. 定义
int pthread_join(pthread_t thread, void **retval);
2. 功能
通过该函数可以将指定的线程资源回收,该函数具有阻塞等待功能,如果指定的线程没有结束,则回收线程会阻塞。
3. 参数
thread 要回收的子线程tid
retval 存放线程退出状态值空间的首地址
4. 返回值
成功 返回0
失败 返回错误码
5. 示例程序
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void * th1(void *arg)
{
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t tid1
pthread_t tid2;
int i = 0 ;
for(i = 0; i<40000; i++)
{
int ret = pthread_create(&tid1, NULL, th1, NULL);
if(ret != 0)
{
break;
}
pthread_join(tid1, NULL);
}
printf("i is %d\n", i);
return 0;
}