linux 下进程间通信就简单多了, 可以采用信号方式.
1. kill 方式
int kill(pid_t pid,int sig), 当pid=-1 将信号广播传送给系统内所有的进程,在Redhat下测试发现, kill -1 SIGRTMIN+10, 只能广播系统关闭命令,关闭所有的用户进程; 因此此路不通,只能一个一个进程的发送信号.
2. sigqueue 方式
遍历所有进程, 然后发送实时信号,达到通知重装配置的目的, 代码如下:
/** *@brief 根据进程名查找相应PID * 在系统 /proc 目录下会找到各个程序运行信息,遍历即可 *@param pName 进程名称 */ pid_t GetPidByName(const char *pName) { DIR *pdir = NULL; struct dirent *pde = NULL; FILE *pf = NULL; char buff[128]; pid_t pid; char szName[128]; pdir = opendir("/proc"); if (!pdir) { perror("open /proc fail.\n"); return -1; } while ((pde = readdir(pdir))) { if ((pde->d_name[0] < '0')|| (pde->d_name[0] > '9')) { continue; } sprintf(buff, "/proc/%s/status", pde->d_name); pf = fopen(buff, "r"); if (pf) { fgets(buff,sizeof(buff),pf); fclose(pf); // 文件第一行格式 Name: top sscanf(buff,"%*s %s",szName); // sscanf不错, 获取进程名 pid=atoi(pde->d_name); if(strcmp(szName,pName)==0) { closedir(pdir); return pid; } } } closedir(pdir); return 0; } // 向进程发送SIGRTMIN+10 的信号 bool SendMessage(const char *pName) { if(pName==NULL) { // 无法广播非关闭信号 //sigqueue(-1,SIGRTMIN+10,NULL); // 实时消息 printf("错误:没有指定进程名\n"); return true; } pid_t pid=GetPidByName(pName); if(pid>0) { printf("信息:发现进程[%s:%d]\n",pName,pid); sigval sVal; sigqueue(pid,SIGRTMIN+10,sVal); // 实时信号 return true; } printf("错误:没有发现 %s\n",pName); return false; }
接收信号:
/** *@brief 安装信号处理函数 */ bool InstallMessage() { struct sigaction act; sigemptyset(&act.sa_mask); act.sa_flags=SA_NODEFER; // 非堵塞方式 act.sa_handler=Messge_Oper; // 安装信号 if(sigaction(SIGRTMIN+10,&act,NULL)<0) { printf("错误:安装信号失败\n"); return false; } return true; } // 回调函数 void Message_Oper(int signo) { }
3. linux下共享内存
服务端:
/** *@brief 向共享内存区写入信息 *@param szMsg 待写入字符串 *@return 执行状态 */ bool WriteMsgToMemory(const char *szMsg) { if(szMsg==NULL) { printf("错误:内容为空\n"); return false; } if(!IsInitial) { if(pthread_mutex_init(&mutex,NULL)!=0) { printf("错误:初始化锁失败\n"); return false; } // 创建一个共享内存对象并返回标识 if((shmid=shmget(MY_SHM_ID,SHM_SIZE,SHM_W|IPC_CREAT))<0) { perror("shmget"); return false; } } void *mem; // 同步锁 pthread_mutex_lock(&mutex); // 映射内存区对象 if((mem=shmat(shmid,0,0))==(void*)-1) perror("shmat"); sprintf((char*)mem,"%s",szMsg); // 写入szMsg shmdt(mem); // 断开共享内存连接 pthread_mutex_unlock(&mutex); return true; }
客户端:
// 读取共享内存内容 bool ReadMemoryMsg(char *szMsg) { int shmid; void *mem; if((shmid=shmget(MY_SHM_ID,SHM_SIZE,SHM_W|IPC_CREAT))<0) { perror("shmget"); return false; } if((mem=shmat(shmid,0,0))==(void*)-1) { perror("shmat"); return false; } // 读取内存 sprintf(szMsg,"%s",(char*)mem); printf("信息:%s\n",szMsg); // 卸载映射 shmdt(mem) ; return true; }
当配置改变时,将内容写入共享内存,然后向每个进程依次发送通知信号, 进程接收到信号后, 直接读取共享内存即可