QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2516|回复: 15

mxd2 做个小更改,免得一次打开多个拨号器冲突

[复制链接]
发表于 2010-9-26 05:11:46 | 显示全部楼层 |阅读模式
又用了popen和bash脚本,但不知道有没有办法只用C函数解决的,不用popen()、ps、wc -l 、grep....
  1. char buf[10];
  2.     FILE *pp;
  3.     if((pp=popen("ps -A|grep mxd|wc -l","r"))!=NULL)
  4.     {
  5.         while(fgets(buf,sizeof(buf),pp))
  6.               {
  7.                this->nostart=atoi(buf);
  8.             }}
  9.     if(nostart>1)
  10.     {
  11.         exit(0);
  12.          }
复制代码

[ 本帖最后由 haulm 于 2010-9-28 22:59 编辑 ]
发表于 2010-9-26 09:09:16 | 显示全部楼层
既然用 Qt,那就都用 Qt 啊
http://doc.qt.nokia.com/solution ... gleapplication.html

KDE 的话,可以用 KUniqueApplication
http://api.kde.org/4.x-api/kdeli ... queApplication.html
回复

使用道具 举报

 楼主| 发表于 2010-9-26 15:04:53 | 显示全部楼层
汗一个。。。
回复

使用道具 举报

 楼主| 发表于 2010-9-26 15:20:12 | 显示全部楼层
这个这个,其实有好处的,自己写的好处就是别人想用mxd就算是mxddd也会冲突的。
回复

使用道具 举报

 楼主| 发表于 2010-9-26 22:09:23 | 显示全部楼层
那个QSingleApplication类并不是Qt4.6默认提供的,而是一个扩展库,我有下载编译出错了。
自己结合大家意见,修改了一下,这样比较严谨了。
  1. char buf[10];
  2.     FILE *pp;
  3.     if((pp=popen("ps -A|grep mxd|wc -l","r"))!=NULL)
  4.     {
  5.         while(fgets(buf,sizeof(buf),pp))
  6.               {
  7.                 this->nostart=atoi(buf);
  8.             }}
  9.     if(nostart>1)
  10.     {
  11.         if(access("/var/run/mxd_status.pid",0)==0)
  12.          {
  13.             printf("Soft mxd allready running!\n");
  14.             exit(0);
  15.         }
  16.     }
  17.     QFile filestatus("/var/run/mxd_status.pid");
  18.     if(filestatus.open(QIODevice::WriteOnly))
  19.     {
  20.         QTextStream stream(&filestatus);
  21.         stream<<"running"<<"\n";
  22.         filestatus.close();
  23.     }
  24. myclass::~myclass()
  25. {
  26.     pppoeStop();
  27.     unlink("/var/run/mxd_status.pid");
  28. }
复制代码
回复

使用道具 举报

 楼主| 发表于 2010-9-26 22:16:09 | 显示全部楼层
之所以用了双项检查是考虑到有一种情况,也就是万一mxd非正常退出,/var/run/mxd_status.pid这个文件没来得及删除而存在,那么mxd永远启动不了了。这种写法,当ps发现的确有可能mxd已经运行才去检查pid文件是否存在,如果也存在说明程序已经运行,exit(0)是非正常退出,所以不会执行unlink删除状态文件。
是否存在说系统有类似mxd名字的程序运行,而且/var/run/mxd_status.pid也非法存在的情况呢,真有的话也太那个了。。。
回复

使用道具 举报

 楼主| 发表于 2010-9-27 07:29:11 | 显示全部楼层
还有一种方法,就是往系统里存状态变量,如果出错最多重启系统出错产物也就被销毁了。或者可以把删除状态文件的指令写入.bash_profile
嗯,检查程序的bash指令行要修正一下,下面的指令确保得到的结果更准确一些:
ps -A|awk '{print $4}'|grep ^mxd$|wc -l
回复

使用道具 举报

发表于 2010-9-27 09:26:31 | 显示全部楼层
最好加进程互斥,这里有详细介绍,各种方法
topic.csdn.net/u/20080619/13/6dae8d21-3aa7-4209-bd44-277f3424240d.html
回复

使用道具 举报

 楼主| 发表于 2010-9-27 23:58:48 | 显示全部楼层
原帖由 zy_sunshine 于 2010-9-27 09:26 发表
最好加进程互斥,这里有详细介绍,各种方法
topic.csdn.net/u/20080619/13/6dae8d21-3aa7-4209-bd44-277f3424240d.html

文件锁很好理解,那个信号锁没看懂。
回复

使用道具 举报

 楼主| 发表于 2010-9-28 10:59:15 | 显示全部楼层
flock() 函数的使用非常奇怪哦,flock 相对于 open,如果你结束了文件的读写(close()),那么文件锁也就自然解除了。我写了一个循环,不急着退出程序,再打开同样的程序,那么第二次的加锁就停在那里等待第一个读取文件的程序结束,否则就不会继续向下面执行。
flock()直接用于Qt程序是否合理呢?比较鬼异,flock返回代表加锁成功,可是我要是在Qt程序中监视flock的返回值,应该是当返回值为0时,程序继续运行,如果不为0,那么程序就此退出。可是事实上相反,我怎么反倒要设置flock如果有返回值0就退出程序,否则继续运行程序呢?困扰。。。由于flock加锁不成功是不返回的,所以你认为Qt程序中用c函数进行文件加锁的方法合理么?

[ 本帖最后由 haulm 于 2010-9-28 11:37 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2010-9-28 11:12:15 | 显示全部楼层
flock(锁定文件或解除锁定)  
相关函数 open,fcntl

表头文件 #include<sys/file.h>

定义函数 int flock(int fd,int operation);

函数说明 flock()会依参数operation所指定的方式对参数fd所指的文件做各种锁定或解除锁定的动作。此函数只能锁定整个文件,无法锁定文件的某一区域。

参数 operation有下列四种情况
LOCK_SH 建立共享锁定。多个进程可同时对同一个文件作共享锁定。
LOCK_EX 建立互斥锁定。一个文件同时只有一个互斥锁定。
LOCK_UN 解除文件锁定状态。
LOCK_NB 无法建立锁定时,此操作可不被阻断,马上返回进程。通常与LOCK_SH或LOCK_EX 做OR(|)组合。
单一文件无法同时建立共享锁定和互斥锁定,而当使用dup()或fork()时文件描述词不会继承此种锁定。

返回值 返回0表示成功,若有错误则返回-1,错误代码存于errno。我补充强调一下,LOCK_EX 建立互斥锁定,如果文件已经被锁则进入等待,无法返回。Qt4 程序如果套入 flock 就不知道最后怎么一回事了,此状况下 flock 如果返回0代表了文件已经被锁,如果不返回反而是文件加锁成功。。。,有待专家解释   LOCK_UN 不能用于 LOCK_EX 的解锁。nihui 知道 Qt4 对文件加锁有自己的方法和函数么?

[[i] 本帖最后由 haulm 于 2010-9-28 11:36 编辑 [/i]]
回复

使用道具 举报

 楼主| 发表于 2010-9-28 11:37:51 | 显示全部楼层
[

  1. char buf[10];
  2.     FILE *pp;
  3.     if((pp=popen("ps -A|awk '{print $4}'|grep ^mxd$|wc -l","r"))!=NULL)
  4.     {
  5.         while(fgets(buf,sizeof(buf),pp))
  6.               {
  7.                 this->nostart=atoi(buf);
  8.             }}
  9.     if(nostart>1)
  10.     {
  11.         int fd;
  12.         fd=open("/var/run/mxd_status.pid", O_WRONLY|O_CREAT);
  13.         if(flock(fd,LOCK_EX)==0)
  14.             {
  15.                exit(0);
  16.             }
  17.     }
复制代码
DISCUZ_CODE_0        ]
回复

使用道具 举报

CecilHarvey 该用户已被删除
发表于 2010-9-28 13:06:53 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

发表于 2010-9-29 13:52:04 | 显示全部楼层
我觉得用socket更好,geany就是真么搞的
启动时先连接,连上了就发个信息,然后退出
连不上就监听,然后继续运行下去。有消息来响应消息。
回复

使用道具 举报

发表于 2010-9-29 17:06:38 | 显示全部楼层
socket 也不错,进程间通信IPC包括很多种,共享内存是最快的。RPC有时会被操作系统优化为共享内存。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-22 15:54 , Processed in 0.048066 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表