目录
传统艺能😎
小编是双非本科大二菜鸟不赘述,欢迎米娜桑来指点江山哦
1319365055
🎉🎉非科班转码社区诚邀您入驻🎉🎉
小伙伴们,满怀希望,所向披靡,打码一路向北
一个人的单打独斗不如一群人的砥砺前行
这是和梦想合伙人组建的社区,诚邀各位有志之士的加入!!
社区用户好文均加精(“标兵”文章字数2000+加精,“达人”文章字数1500+加精)
直达: 社区链接点我
Linux线程安全😊
临界资源: 多线程执行流共享的资源叫做临界资源。
临界区: 每个线程内部,访问临界资源的代码,就叫做临界区。
互斥: 任何时刻有且只有一个执行流进入临界区,访问临界资源,互斥对临界资源起保护作用。
原子性: 不会被任何调度机制打断的操作,该操作只有两态:完成和未完成
说明一下,我们如果需要进行进程间通信,我们就需要先创建一个第三方资源,让不同的进程看到同一份资源,但是由于第三方资源可以由不同的模块来提供,所以就有了不同的通信方式,这个第三方资源部就是临界资源,访问第三方资源的地方就是临界区。
为什么说线程是神就是因为线程不需要创建第三方资源就可以进行通信,大部分资源时共享的,比如线程进行计数时我们在全局区定义count 变量,每隔一秒打印一次:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int count = 0;
void* Routine(void* arg)
{
while (1){
count++;
sleep(1);
}
pthread_exit((void*)0);
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, Routine, NULL);
while (1){
printf("count: %d\n", count);
sleep(1);
}
pthread_join(tid, NULL);
return 0;
}
结果如下:
这里的 count 就叫做临界资源,因为它被多个执行流共享,而主线程中的printf和新线程中count++就叫做临界区,因为这些代码对临界资源进行了访问
原子性&互斥🤣
原子性指的是不可被分割的操作,该操作不会被任何调度机制打断,该操作只有两态,要么完成,要么未完成。在多线程情况下,如果这多个执行流都自顾自的对临界资源进行操作,那么此时就可能导致数据不一致的问题。解决该问题的方案就叫做互斥,互斥的作用就是,保证在任何时候有且只有一个执行流进入临界区对临界资源进行访问。
我们可以模拟实现一个抢票系统,票的剩余张数定义为全局变量,主线程创建四个新线程,让这四个新线程进行抢票,当票被抢完后这四个线程自动退出:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int tickets = 1000;
void* TicketGrabbing(void* arg)
{
const char* name = (char*)arg;
while (1){
if (tickets > 0){
usleep(10000);
printf("[%s] get a ticket, left: %d\n", name, --tickets);
}
else{
break;
}
}
printf("%s quit!\n", name);
pthread_exit((void*)0);
}
int main()
{
pthread_t t1, t2, t3, t4;
pthread_create(&t1, NULL, TicketGrabbing, "thread 1");
pthread_create(&t2