linux 下进程间通信就简单多了, 可以采用信号方式.

 

    1. kill 方式

     int kill(pid_t pid,int sig), 当pid=-1 将信号广播传送给系统内所有的进程,在Redhat下测试发现, kill -1 SIGRTMIN+10, 只能广播系统关闭命令,关闭所有的用户进程; 因此此路不通,只能一个一个进程的发送信号.

    2. sigqueue 方式

    遍历所有进程, 然后发送实时信号,达到通知重装配置的目的, 代码如下: 

#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>

/**
*@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;
}

 

   当配置改变时,将内容写入共享内存,然后向每个进程依次发送通知信号, 进程接收到信号后, 直接读取共享内存