Linux20 -- 线程安全、保证线程安全的示例代码
创始人
2024-02-06 05:37:47

一、线程安全

线程安全即就是在多线程运行的时候,不论线程的调度顺序怎样,最终的结果都是
一样的、正确的。那么就说这些线程是安全的。

线程安全:多线程程序,无论调度顺序咋样,都可以得到正确一致的结果。安全–正确性。
同步,线程安全的函数/可重入函数。

要保证线程安全需要做到:
1) 对线程同步,保证同一时刻只有一个线程访问临界资源。
2)在多线程中使用线程安全的函数(可重入函数),所谓线程安全的函数指的是:如果一个
函数能被多个线程同时调用且不发生竟态条件,则我们程它是线程安全的。

二、保证线程安全的示例代码

1、strtok函数的线程调用示例,不保证线程安全:

#include 
#include 
#include 
#include 
#include void* fun(void *arg)
{char buff[]={"a b c d e f g h j"};char *s = strtok(buff," ");while(s != NULL){printf("fun s = %s\n",s);sleep(1);s = strtok(NULL," ");}
}int main()
{pthread_t id;pthread_create(&id,NULL,fun,NULL);char arr[]="1 2 3 4 5 6 7 8 9";char *s = strtok(arr," ");while(s != NULL){printf("main s = %s\n",s);sleep(1);s = strtok(NULL," ");}pthread_join(id,NULL);}

运行结果:
在这里插入图片描述

2、strtok_r函数的线程调用

#include 
#include 
#include 
#include 
#include void* fun(void *arg)
{char buff[]={"a b c d e f g h j"};char * ptr = NULL;char *s = strtok_r(buff," ",&ptr);while(s != NULL){printf("fun s = %s\n",s);sleep(1);s = strtok_r(NULL," ",&ptr);}
}int main()
{pthread_t id;pthread_create(&id,NULL,fun,NULL);char arr[]="1 2 3 4 5 6 7 8 9";char *ptr = NULL;char *s = strtok_r(arr," ",&ptr);while(s != NULL){printf("main s = %s\n",s);sleep(1);s = strtok_r(NULL," ",&ptr);}pthread_join(id,NULL);}

运行结果:

在这里插入图片描述

2、多线程中某个线程调用 fork(),子进程会有和父进程相同数量的线程吗?

ps -ef
ps -eLf --查看线程id

#include 
#include 
#include 
#include 
#include void* fun(void *arg)
{for(int i = 0;i < 5;i++){printf("fun run , pid = %d\n",getpid());sleep(1);}
}int main()
{pthread_t id;pthread_create(&id,NULL,fun,NULL);for( int i = 0; i < 5 ; i++){printf("main run , pid = %d\n",getpid());sleep(1);}pthread_join(id,NULL);exit(0);
}

运行结果:

在这里插入图片描述

原理:

Linux实现线程的机制非常独特。从内核的角度来说,它并没有线程这个概念。Linux把所有的线程都当做进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个与其他进程共享某些资源的进程。每个线程都拥有唯一隶属于自己的 task_struct,所以在内核中,它看起来就像是一个普通的进程(只是线程和其他一些进程共享某些资源,如地址空间)。

3、父进程被加锁的互斥锁 fork 后在子进程中是否已经加锁?

fork会将锁复制,但为保证安全,会将锁默认锁上。
为防止出现错误。父子进程在使用锁的时候,可以先对其进行解锁,再使用锁。

解决方法:pthread_atfork()

test3.c

#include 
#include 
#include 
#include 
#include 
#include pthread_mutex_t mutex;void* fun(void *arg)
{pthread_mutex_lock(&mutex);printf("fun lock\n");sleep(5);pthread_mutex_unlock(&mutex);printf("fun unlock\n");
}int main()
{pthread_t id;pthread_mutex_init(&mutex,NULL);//对锁进行初始化pthread_create(&id,NULL,fun,NULL);sleep(1);//等待线程运行,等其进行加锁pid_t pid = fork(); if(pid == -1){exit(0);}if(pid == 0){printf("子进程将要加锁\n");pthread_mutex_lock(&mutex);printf("子进程加锁成功\n");pthread_mutex_unlock(&mutex);}else{wait(NULL);//子进程未结束,会阻塞printf("main over\n");}pthread_join(id,NULL);exit(0);
}

test4.c //使用pthread_atfork

#include 
#include 
#include 
#include 
#include 
#include pthread_mutex_t mutex;void* fun(void *arg)
{pthread_mutex_lock(&mutex);printf("fun lock\n");sleep(5);pthread_mutex_unlock(&mutex);printf("fun unlock\n");
}void at_lock()
{pthread_mutex_lock(&mutex);
}void at_unlock()
{pthread_mutex_unlock(&mutex);
}int main()
{pthread_t id;pthread_atfork(at_lock,at_unlock,at_unlock);pthread_mutex_init(&mutex,NULL);//对锁进行初始化pthread_create(&id,NULL,fun,NULL);sleep(1);//等待线程运行,等其进行加锁pid_t pid = fork(); if(pid == -1){exit(0);}if(pid == 0){printf("子进程将要加锁\n");pthread_mutex_lock(&mutex);printf("子进程加锁成功\n");pthread_mutex_unlock(&mutex);}else{wait(NULL);//子进程未结束,会阻塞printf("main over\n");}pthread_join(id,NULL);exit(0);
}

运行结果:

在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...