haulm 发表于 2010-9-26 05:11:46

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

又用了popen和bash脚本,但不知道有没有办法只用C函数解决的,不用popen()、ps、wc -l 、grep.... char buf;
    FILE *pp;
    if((pp=popen("ps -A|grep mxd|wc -l","r"))!=NULL)
    {
      while(fgets(buf,sizeof(buf),pp))
            {
               this->nostart=atoi(buf);
            }}
    if(nostart>1)
    {
      exit(0);
         }

[ 本帖最后由 haulm 于 2010-9-28 22:59 编辑 ]

nihui 发表于 2010-9-26 09:09:16

既然用 Qt,那就都用 Qt 啊
http://doc.qt.nokia.com/solutions/4/qtsingleapplication/qtsingleapplication.html

KDE 的话,可以用 KUniqueApplication
http://api.kde.org/4.x-api/kdelibs-apidocs/kdeui/html/classKUniqueApplication.html

haulm 发表于 2010-9-26 15:04:53

汗一个。。。

haulm 发表于 2010-9-26 15:20:12

这个这个,其实有好处的,自己写的好处就是别人想用mxd就算是mxddd也会冲突的。 :mrgreen:

haulm 发表于 2010-9-26 22:09:23

那个QSingleApplication类并不是Qt4.6默认提供的,而是一个扩展库,我有下载编译出错了。
自己结合大家意见,修改了一下,这样比较严谨了。char buf;
    FILE *pp;
    if((pp=popen("ps -A|grep mxd|wc -l","r"))!=NULL)
    {
      while(fgets(buf,sizeof(buf),pp))
            {
                this->nostart=atoi(buf);
            }}
    if(nostart>1)
    {
      if(access("/var/run/mxd_status.pid",0)==0)
         {
            printf("Soft mxd allready running!\n");
            exit(0);
      }
    }
    QFile filestatus("/var/run/mxd_status.pid");
    if(filestatus.open(QIODevice::WriteOnly))
    {
      QTextStream stream(&filestatus);
      stream<<"running"<<"\n";
      filestatus.close();
    }
myclass::~myclass()
{
    pppoeStop();
    unlink("/var/run/mxd_status.pid");
}

haulm 发表于 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也非法存在的情况呢,真有的话也太那个了。。。

haulm 发表于 2010-9-27 07:29:11

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

zy_sunshine 发表于 2010-9-27 09:26:31

最好加进程互斥,这里有详细介绍,各种方法
topic.csdn.net/u/20080619/13/6dae8d21-3aa7-4209-bd44-277f3424240d.html

haulm 发表于 2010-9-27 23:58:48

原帖由 zy_sunshine 于 2010-9-27 09:26 发表 http://www.linuxfans.org/bbs/images/common/back.gif
最好加进程互斥,这里有详细介绍,各种方法
topic.csdn.net/u/20080619/13/6dae8d21-3aa7-4209-bd44-277f3424240d.html
文件锁很好理解,那个信号锁没看懂。

haulm 发表于 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 编辑 ]

haulm 发表于 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代表了文件已经被锁,如果不返回反而是文件加锁成功。。。,有待专家解释:mrgreen: LOCK_UN 不能用于 LOCK_EX 的解锁。nihui 知道 Qt4 对文件加锁有自己的方法和函数么?

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

haulm 发表于 2010-9-28 11:37:51

[
char buf;
    FILE *pp;
    if((pp=popen("ps -A|awk '{print $4}'|grep ^mxd$|wc -l","r"))!=NULL)
    {
      while(fgets(buf,sizeof(buf),pp))
            {
                this->nostart=atoi(buf);
            }}
    if(nostart>1)
    {
      int fd;
      fd=open("/var/run/mxd_status.pid", O_WRONLY|O_CREAT);
      if(flock(fd,LOCK_EX)==0)
            {
               exit(0);
            }
    }DISCUZ_CODE_0        ]

CecilHarvey 发表于 2010-9-28 13:06:53

wkt 发表于 2010-9-29 13:52:04

我觉得用socket更好,geany就是真么搞的
启动时先连接,连上了就发个信息,然后退出
连不上就监听,然后继续运行下去。有消息来响应消息。

zy_sunshine 发表于 2010-9-29 17:06:38

socket 也不错,进程间通信IPC包括很多种,共享内存是最快的。RPC有时会被操作系统优化为共享内存。
页: [1] 2
查看完整版本: mxd2 做个小更改,免得一次打开多个拨号器冲突