项目场景:
在多线程中使用信号量时需要先根据key去semget创建信号量,而key的创建一般则是由系统ftok给出,(当然可以指定,指定key在这里认为不安全)。
问题描述:
在测试时,发现一种异常情况,信号量递增超出系统限制,导致后续创建信号量失败,引发了其他显式的错误。
原因分析:
将ftok创建的key值打印发现异常情况引起key值的变化。
首先查看ftok函数:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
这里不得不说ftok的一个陷阱了:
可见key是通过pathname和id共同创建的,按道理说path那么相同那么key一定就会相同吗?
这里就会给我们一个误解,即只要文件的路径,名称和子序列号不变,那么得到的key值永远就不会变。其实不是这样的,通过实验发现,如果这个文件路径删除重建之后的key值会变,那么就是说pathname不仅仅只是作为参数,而在ftok函数内部引用了文件的属性。
这里在多线程中就会引发不可预料的错误。
解决方案:
确保key值不变。
1、确保ftok()的文件不被删除,要么不用ftok(),指定一个固定的key值,防止ftok引发异常场景。
2、自己动态创建文件,不要引用系统中自动创建的文件。这样就可以避免一些操作导致引用的系统中的文件变化(重新创建、删除、覆盖等情况),引用由自己动态创建的文件最安全,自己完全可以限制文件的操作(创建、删除、覆盖等操作)。