2010-11-06 75 views
0

谁能告诉我,为什么下面的不作为互斥体的一个例子的LinuxLinux互斥锁检查程序是否已经在运行?

#include <pthread.h> 
int main(){ 
pthread_mutex_t start; 
if (pthread_mutex_init(&start, NULL) != 0){ 
    printf("err!"); 
    return(1); 
} 
if (pthread_mutex_lock(&start) != 0){ 
    printf("err!"); 
    return(1); 
} 

pthread_mutex_unlock(&start); 
pthread_mutex_destroy(&start); 
} 
+0

为什么不使用pid文件&'kill(pid,0)'?它可能不是最可靠的解决方案,但实际上可用于所有应用。 – jweyrich 2010-11-07 01:03:56

回答

8

并行线程互斥是一个程序中同步线程下工作。如果你开始这个程序两次,你会得到两个不同的互斥体。为了在多个进程之间进行同步,还有其他工具(在这种情况下文件锁定可能是最简单的)。

+1

有进程共享互斥体('pthread_mutexattr_setpshared()')。你必须把它们放在共享内存中 - 创建一个锁文件可能要容易得多。 – nos 2010-11-07 17:06:49

0

pthread互斥锁旨在用于单个进程中的线程;如果它位于共享内存中,它也可能工作,但是您在上面分配它的方式,两者都不会。

因此,调用两个程序副本,创建两个互斥体,每个都需要自己,每个人都很高兴 - 除非这不是您想要的。

我认为只允许一个副本的最简单方法是打开一个文件进行写入并对其进行独占文件锁定(请参阅flock())。

另一种可能性是尝试绑定抽象名称空间中的unix套接字;请参阅man unix(7),但是这是Linux专用的。

0

我发现一个进程检查并查看另一个进程是否还在运行的最佳方式是使用锁定文件,正如在注释中添加了信号一样。

如果程序B不应该开始,如果程序A尚未启动,活着并响应,或者程序A不负责启动程序B,但应该做一些不同的事情,如果程序B没有启动一段时间。这实际上是一种非常常见的情况。

试试这个:

  • 计划A开始,写入其PID到/var/run/a.pid
  • B计划开始,写入其PID到/var/run/b.pid
  • 程序B读取/var/run/a.pid并把它发送一个SIGUSR1
  • 程序A对SIGUSR1信号处理程序读取/var/run/b.pid并把它发送一个SIGUSR1为ACK
  • 方案B知道程序A正在运行并可以继续运行
  • 程序A知道程序B已经启动,并可以改变其行为

这是非常简化和基本的IPC,但工程。一个更优雅的方法是通过mmap()在进程之间共享内存段,但即使如此,您也不应该相信锁是另一个进程实际响应的标志,特别是在第二个进程中没有处理饥饿问题。相反的情况也是如此。

这也是一个非常以POSIX为中心的答案,如果它不适用,请详细描述你的平台。

相关问题