1 -> 分离线程
2 -> Linux线程互斥
2.1 -> 进程线程间的互斥相关背景概念
2.2 -> 互斥量mutex
2.3 -> 互斥量的接口
2.4 -> 互斥量实现原理探究
3 -> 可重入VS线程安全
3.1 -> 概念
3.2 -> 常见的线程不安全的情况
3.3 -> 常见的线程安全的情况
3.4 -> 常见可重入的情况
3.5 -> 可重入与线程安全联系
3.6 -> 可重入与线程安全区别
4 -> 常见锁的概念
4.1 -> 死锁
4.2 -> 死锁四个必要条件
4.3 -> 避免死锁
int pthread_detach(pthread_t thread);
可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离。
pthread_detach(pthread_self());
joinable和分离是冲突的,一个线程不能既是joinable又是分离的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
void* thread_run(void* arg)
{
pthread_detach(pthread_self());
printf("%s\n", (char*)arg);
return NULL;
}
int main(void)
{
pthread_t tid;
if (pthread_create(&tid, NULL, thread_run, "thread1run...") != 0 )
{
printf("create thread error\n");
return 1;
}
int ret = 0;
sleep(1);//很重要,要让线程先分离,再等待
if (pthread_join(tid, NULL) == 0)
{
printf("pthread wait success\n");
ret = 0;
}
else
{
printf("pthread wait failed\n");
ret = 1;
}
return ret;
}
// 操作共享变量会有问题的售票系统代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
int ticket = 100;
void* route(void* arg)
{
char* id = (char*)arg;
while (1)
{
if (ticket > 0)
{
usleep(1000);
printf("%s sells ticket:%d\n", id, ticket);
ticket--;
}
else
{
break;
}
}
}
int main(void)
{
pthread_t t1, t2, t3, t4;
pthread_create(&t1, NULL, route, "thread 1");
pthread_create(&t2, NULL, route, "thread 2");
pthread_create(&t3, NULL, route, "thread 3");
pthread_create(&t4, NULL, route, "thread 4");
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
}
为什么可能无法获得争取结果?
取出 ticket--部分的汇编代码objdump -d a.out > test.objdump15240064b:8b 05 e3 04 20 00mov0x2004e3(%rip),%eax# 600b34 <ticket>153400651:83 e8 01sub$0x1,%eax154400654:89 05 da 04 20 00mov%eax,0x2004da(%rip)# 600b34 <ticket>
--操作并不是原子操作,而是对应三条汇编指令:
要解决以上问题,需要做到三点:
初始化互斥量
初始化互斥量有两种方法:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
int pthread_mutex_init(pthread_mutex_t* restrict mutex, const
pthread_mutexattr_t* restrict attr);
参数:
mutex:要初始化的互斥量
attr:NULL
销毁互斥量
销毁互斥量需要注意:
int pthread_mutex_destroy(pthread_mutex_t* mutex);
互斥量加锁和解锁
int pthread_mutex_lock(pthread_mutex_t* mutex);
int pthread_mutex_unlock(pthread_mutex_t* mutex);
返回值:成功返回 0, 失败返回错误号
调用pthread_ lock时,可能会遇到以下情况:
改进上面的售票系统:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
int ticket = 100;
pthread_mutex_t mutex;
void* route(void* arg)
{
char* id = (char*)arg;
while (1)
{
pthread_mutex_lock(&mutex);
if (ticket > 0)
{
usleep(1000);
printf("%s sells ticket:%d\n", id, ticket);
ticket--;
pthread_mutex_unlock(&mutex);
// sched_yield(); 放弃 CPU
}
else
{
pthread_mutex_unlock(&mutex);
break;
}
}
}
int main(void)
{
pthread_t t1, t2, t3, t4;
pthread_mutex_init(&mutex, NULL);
pthread_create(&t1, NULL, route, "thread 1");
pthread_create(&t2, NULL, route, "thread 2");
pthread_create(&t3, NULL, route, "thread 3");
pthread_create(&t4, NULL, route, "thread 4");
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_join(t4, NULL);
pthread_mutex_destroy(&mutex);
}
感谢各位大佬支持!!!
互三啦!!!