1.
wait
waitpid //1.理解函数的功能
//2.使用
2.线程
a.线程概念
b.线程 与 进程关系
线程存在于进程中
线程 --- 执行的单位
进程 --- 资源分配单位
创建 和 调度
c.线程组成
d.线程操作 (函数接口)
创建线程 pthread_create
posix thread create
线程执行 ---体现在线程执行函数 (回调函数)
线程退出 ---pthread_exit()
线程结束方式:
1.pthread_exit //pthread_join
2.从线程执行函数中return //此时效果等价于pthread_exit
3.pthread_cancel //线程可以被取消
4.任何一个线程调用了exit
或者
主线程 (main函数) return
都会造成 进程结束
线程资源回收 ---pthread_join
int pthread_cancel(pthread_t thread);
功能:
发送 取消的请求
参数:
thread //表示要发送的线程的tid号
返回值:
成功 0
失败 错误码
线程资源回收
1.pthread_join //需要自己回收 ---线程的属性 (可结合性) --- 一般是子线程 在较短时间内运行完
2.pthread_detach //可分离属性 ---子线程运行很久才结束 --- 设置分离属性
函数:
pthread_detach();
int pthread_detach(pthread_t thread);
功能:
分离线程
参数:
thread 要分离的线程的tid
返回值:
成功 0
失败 错误码
---------------------------------------------------------------
总结:
1.创建 -- pthread_create
2.执行 -- 线程执行函数
3.退出 -- pthread_exit
return //线程执行函数中
pthread_cancel
exit() //return 从main
4.资源回收
可结合性 --- pthread_join //这种用于 ,线程任务较短,主线程需要关心子线程状态
可分离性 --- pthread_detach //子程序执行任务较长,主线程也不需要关心子线程状态
-----------------------------------------------------------------
对比 线程 和 进程
1.线程 vs 进程
线程 CPU执行的最小单位
进程 资源分配和任务调度基本单位
2. 各自特点 (优缺点)
//1.创建 和 调度
线程
创建速度快
调度速度快
//并发程度 更高
//2. 安全性
线程
好处:
共享了进程的数据空间
共享数据方面 方便
缺点:
安全性不好 //
带来资源竞争 //专门的技术 解决资源竞争 --- 互斥 同步
进程
进程空间相互独立
好处,
安全性好
缺点:
进程间共享数据不方便 //进程间通信 (管道,信号,共享内存)
//3. 编程
--------------------------------------------------------------------------------
线程间的资源竞争:
共享资源: 临界资源
临界区 : 访问共享资源(临界资源)那段代码
机制:
互斥锁
互斥 排他性 --- 要么不访问 要访问就是一次完整操作 (原子操作)
锁 //
//软件层面上的锁
//锁的操作机制
框架:
定义互斥锁 ==》初始化锁 ==》加锁 ==》解锁 ==》销毁
**** *** ***
定义互斥锁:
pthread_mutex_t mutex;
互斥锁类型 互斥锁变量 内核对象
初始化锁
pthread_mutex_init(); //初始化一把锁
加锁 //加锁 加在 要访问临界资源的地方
pthread_mutex_lock(); //上锁
解锁
pthread_mutex_unlock(); //解锁 临界资源访问之后就解开
销毁
pthread_mutex_destroy();//销毁一把锁
pthread_mutex_init()
功能:
初始化 互斥锁
int pthread_mutex_init(
pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr
);
参数:
@mutex //就是要初始化的 互斥锁变量
@attr //属性
//NULL 默认属性 --- 普通锁
//读写锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数:
@mutex //要操作的那把锁
int pthread_mutex_destroy(pthread_mutex_t *mutex); //用完之后锁要销毁
练习:
定义一个全局char buf[20];
线程1
把0~9 这10个 数字字符依次存放到buf中
for (i = 0; )
然后 打印 //printf("%s\n",buf);
线程2
把abcdefghij 这10个 字母字符依次存放到buf中
然后 打印 //printf("%s\n",buf);
总结:
//锁是一种线程间 同步机制
//互斥锁 -- 保证线程对于共享资源的排他性访问 。
保证每个线程访问时的原子性操作
//操作
//初始化 一把锁
// 动态初始化 pthread_mutex_init
// 静态初始化 用初始化的宏
//加锁
//解锁
//销毁
--------------------------------------------------------------
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void* increment_counter(void* arg)
{
for (int i = 0; i < 10000; ++i)
{
// 锁定互斥锁,等待直到获得锁
pthread_mutex_lock(&mutex);
// 安全地更新计数器
counter++;
printf("Counter is now %d\n", counter);
// 释放互斥锁
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
pthread_t t1, t2;
// 创建两个线程
pthread_create(&t1, NULL, increment_counter, NULL);
pthread_create(&t2, NULL, increment_counter, NULL);
// 等待线程结束
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Final counter value is %d\n", counter);
return 0;
}
------------
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void* increment_counter_trylock(void* arg)
{
for (int i = 0; i < 10000; ++i)
{
// 尝试锁定互斥锁
if (pthread_mutex_trylock(&mutex) == 0)
{
// 成功获取锁,更新计数器
counter++;
printf("Counter is now %d\n", counter);
// 释放互斥锁
pthread_mutex_unlock(&mutex);
} else {
// 未能获取锁,可以做一些其他的事情或者简单地重试
// 这里我们选择简单的重试
continue;
}
}
return NULL;
}
int main() {
pthread_t t1, t2;
// 创建两个线程
pthread_create(&t1, NULL, increment_counter_trylock, NULL);
pthread_create(&t2, NULL, increment_counter_trylock, NULL);
// 等待线程结束
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Final counter value is %d\n", counter);
return 0;
}
-----------------------------------------------------------------