为什么我们在初始化信号量之前取消链接?
Why We unlink semaphores before we initializes them?
我正在研究一段代码(哲学家用餐问题的解决方案),然后是程序员初始化他的信号量的部分,但是在他初始化每个信号量之前,他首先取消链接。
int sems_init(t_args *args)
{
sem_unlink("forking");
args->sem_forks = sem_open("forking", O_CREAT, 0644,
args->philo_amount);
if (args->sem_forks == SEM_FAILED)
return (1);
sem_unlink("writing");
args->sem_write = sem_open("writing", O_CREAT, 0644, 1);
if (args->sem_write == SEM_FAILED)
return (1);
sem_unlink("meal");
args->sem_meal = sem_open("meal", O_CREAT, 0644, 1);
if (args->sem_meal == SEM_FAILED)
return (1);
return (0);
}
我用谷歌搜索了一下,似乎 SO 社区中没有任何资源实际提到了这个。或者至少我没有找到它。
信号量初始化不会在循环中调用,也不会在此初始化之前调用(这是它们第一次在代码中初始化)。这加剧了我的困惑,我试图从代码中注释 sem_unlink()
部分,但它停止工作,即取消链接部分正在做某事,问题 为什么我们在初始化之前删除信号量即使初始化可能是第一个。
why we delete a semaphore before initialize it even though the initialization might be the first one.
因为 sem_open()
创建的命名信号量具有内核持久性。这是命名它们的部分意义所在。他们活到
- 它们已取消链接,并且没有进程打开它们,或者
- 系统已关闭
如果你想确保你正在创建一个新的(命名的)信号量而不是打开一个现有的信号量,那么在 sem_open()
调用之前取消链接名称很有可能。但是,如果你想确定,那么你还应该在标志中添加O_EXCL
。如果具有给定名称的信号量已经存在,这将导致 sem_open()
失败,例如如果另一个进程在 sem_unlink()
和 sem_open()
之间创建了一个信号量。
另请注意,信号量名称应以 /
开头(请参阅 sem_overview(7))。有些图书馆不强制执行,但您不应该通过省略它来无缘无故地引入可移植性问题。
另一方面,如果您只想为单个进程使用信号量,而该进程的生命周期受其宿主进程的限制,那么使用命名信号量只会让您的生活变得艰难。在这种情况下,使用匿名对象会更好,声明为 sem_t
类型的对象并通过 sem_init()
函数而不是 sem_open()
函数初始化。这将解决所有持久性和不相关的问题。
我正在研究一段代码(哲学家用餐问题的解决方案),然后是程序员初始化他的信号量的部分,但是在他初始化每个信号量之前,他首先取消链接。
int sems_init(t_args *args)
{
sem_unlink("forking");
args->sem_forks = sem_open("forking", O_CREAT, 0644,
args->philo_amount);
if (args->sem_forks == SEM_FAILED)
return (1);
sem_unlink("writing");
args->sem_write = sem_open("writing", O_CREAT, 0644, 1);
if (args->sem_write == SEM_FAILED)
return (1);
sem_unlink("meal");
args->sem_meal = sem_open("meal", O_CREAT, 0644, 1);
if (args->sem_meal == SEM_FAILED)
return (1);
return (0);
}
我用谷歌搜索了一下,似乎 SO 社区中没有任何资源实际提到了这个。或者至少我没有找到它。
信号量初始化不会在循环中调用,也不会在此初始化之前调用(这是它们第一次在代码中初始化)。这加剧了我的困惑,我试图从代码中注释 sem_unlink()
部分,但它停止工作,即取消链接部分正在做某事,问题 为什么我们在初始化之前删除信号量即使初始化可能是第一个。
why we delete a semaphore before initialize it even though the initialization might be the first one.
因为 sem_open()
创建的命名信号量具有内核持久性。这是命名它们的部分意义所在。他们活到
- 它们已取消链接,并且没有进程打开它们,或者
- 系统已关闭
如果你想确保你正在创建一个新的(命名的)信号量而不是打开一个现有的信号量,那么在 sem_open()
调用之前取消链接名称很有可能。但是,如果你想确定,那么你还应该在标志中添加O_EXCL
。如果具有给定名称的信号量已经存在,这将导致 sem_open()
失败,例如如果另一个进程在 sem_unlink()
和 sem_open()
之间创建了一个信号量。
另请注意,信号量名称应以 /
开头(请参阅 sem_overview(7))。有些图书馆不强制执行,但您不应该通过省略它来无缘无故地引入可移植性问题。
另一方面,如果您只想为单个进程使用信号量,而该进程的生命周期受其宿主进程的限制,那么使用命名信号量只会让您的生活变得艰难。在这种情况下,使用匿名对象会更好,声明为 sem_t
类型的对象并通过 sem_init()
函数而不是 sem_open()
函数初始化。这将解决所有持久性和不相关的问题。