免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2290 | 回复: 16
打印 上一主题 下一主题

请教关于C99中传递消息给别的进程的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-08 15:57 |只看该作者 |倒序浏览
现在要写一段代码,保证程序只运行一个实例,使用文件锁来完成。

在程序启动时,如果检测到有别的进程锁定了特定文件,就发送SIGUSR1信号给正在运行的那个进程,自己退出。

如后面的那段代码,如果直接用"gcc main.c -o test",那么编译生成的结果就没有任何问题,也能够完成预期的功能。一旦有一个进程在运行,那么以后的功能都会自动退出,第一个运行的进程每次都能收到SIGUSR1信号。

但是当编译的时候,使用"gcc -std=c99 main.c -o test"时,就会出现问题,首先,编译的时候会出现一个warning,
main.c:86: warning: implicit declaration of function `kill'

对于生成的程序,先执行一个,程序是正常的,然后再执行,可以正确发送信号,结果也正常,但是再执行一次的时候,就会出现错误,第三次执行的程序检测到了第一个进程,并发送信号给第一个进程,自己退出。但是第一个进程这个时候也会退出。

如果在SIGUSR1信号的handle函数中加入"signal (SIGUSR1, handle_sigusr1);",就不会出现这种情况。

实在不知道在c99中应该怎样给另一个进程发送消息,请各位高手指点一下。谢谢!

代码如下

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>

static void
handle_sigusr1 (int value)
{
  printf ("Get the signal SIGUSR1\n");
  //signal (SIGUSR1, handle_sigusr1);
}

static pid_t
testlock (char *fname)
{
  int fd;
  struct flock fl;

  fd = open (fname, O_WRONLY, S_IWUSR);
  if (fd < 0)
    {
      if (errno == ENOENT)
        {
          return 0;
        }
      else
        {
          perror ("Test lock open file");
          return -1;
        }
    }

  fl.l_type = F_WRLCK;
  fl.l_whence = SEEK_SET;
  fl.l_start = 0;
  fl.l_len = 0;

  if (fcntl (fd, F_GETLK, &fl) < 0)
    {
      close (fd);
      return -1;
    }
  close (fd);

  if (fl.l_type == F_UNLCK)
    return 0;

  return fl.l_pid;
}

static void
setlock (char *fname)
{
  int fd;
  struct flock fl;

  fd = open (fname, O_WRONLY|O_CREAT, S_IWUSR);
  if (fd < 0)
    {
      perror ("Set lock open file");
      return ;
    }

  fl.l_type = F_WRLCK;
  fl.l_whence = SEEK_SET;
  fl.l_start = 0;
  fl.l_len = 0;

  if (fcntl (fd, F_SETLK, &fl) < 0)
    {
      perror ("Lock file");
      close (fd);
    }
}

int
main (int argc, char* argv[])
{
  pid_t           lockapp;

  lockapp = testlock ("/tmp/test.lock");
  if (lockapp > 0)
    {
      kill (lockapp, SIGUSR1);
      return 0;
    }
  setlock ("/tmp/test.lock");

  signal (SIGUSR1, handle_sigusr1);

  while (1)
    {
      sleep(10);
    }
}

论坛徽章:
0
2 [报告]
发表于 2007-01-08 16:00 |只看该作者
#include <sys/types.h>  ?

论坛徽章:
0
3 [报告]
发表于 2007-01-08 16:05 |只看该作者
原帖由 albcamus 于 2007-1-8 16:00 发表
#include <sys/types.h>  ?


试验了一下,加上这一行,跟原来的情况还是一样的。

论坛徽章:
0
4 [报告]
发表于 2007-01-08 16:23 |只看该作者
确实如此.

论坛徽章:
0
5 [报告]
发表于 2007-01-08 16:27 |只看该作者
可能是头文件的问题,明显的,signal的语义变成非BSD的.(man signal)

论坛徽章:
0
6 [报告]
发表于 2007-01-08 16:34 |只看该作者
在signal.h中,kill函数的定义是
#ifdef __USE_POSIX
extern int kill (__pid_t __pid, int __sig) __THROW;
#endif /* Use POSIX.  */

我有点儿怀疑在使用"-std=c99"时,宏__USE_POSIX是无效的,所以编译的时候就会报warning。同样,使用sigqueue函数时,跟使用kill的结果是一样的。
不过不知道为什么加上"-std=c99"时会引出这样的问题。

论坛徽章:
0
7 [报告]
发表于 2007-01-08 16:38 |只看该作者
这个问题的确很奇特。
兄台的GCC版本多少?
我跑到那个龙芯盒子上运行了一把,问题跟你一样,它的是4。1。2

我又特地跑到NETBSD上运行了一把,结果没有这样的问题……看来这个问题并不普遍:我的gcc是3.3.3

论坛徽章:
0
8 [报告]
发表于 2007-01-08 16:39 |只看该作者
原帖由 融化的冰山 于 2007-1-8 16:34 发表
在signal.h中,kill函数的定义是
#ifdef __USE_POSIX
extern int kill (__pid_t __pid, int __sig) __THROW;
#endif /* Use POSIX.  */

我有点儿怀疑在使用"-std=c99"时,宏__USE_POSIX是无效的, ...


应该不是宏的问题,因为编译加上-D__USE_POSIX也是一样的。

论坛徽章:
0
9 [报告]
发表于 2007-01-08 16:42 |只看该作者
原帖由 albcamus 于 2007-1-8 16:39 发表


应该不是宏的问题,因为编译加上-D__USE_POSIX也是一样的。

你加上-D __USE_POSIX也会被undefine掉。我估计是4。X的GCC自动把这个宏取消了。

论坛徽章:
0
10 [报告]
发表于 2007-01-08 16:42 |只看该作者
原帖由 assiss 于 2007-1-8 16:38 发表
这个问题的确很奇特。
兄台的GCC版本多少?
我跑到那个龙芯盒子上运行了一把,问题跟你一样,它的是4。1。2

我又特地跑到NETBSD上运行了一把,结果没有这样的问题……看来这个问题并不普遍:我的gcc是3.3.3


我的gcc版本是3.4.4,运行在debian上,kenrel版本是2.6.8-3-686,很有可能是gcc版本不同结果也不同,我也用gcc 3.3.3试验一下。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP