精灵程序
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <sys/resource.h>
#include <sys/file.h>
#define SPACE 0
#define DATA 1
#define MEM_PATH "/mnt/share/project/project_01/"
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
void shm_init(int id,int num,int val);
void P(int id,int num);
void V(int id,int num);
void my_log(char *str);
void sumu(void);
int main()
{
pid_t a;
int max_fd,i;
/***************************************************
1.忽略SIGHUP信号(关闭终端),防止进程被CTTY控制终端关闭
*****************************************************/
signal(SIGHUP,SIG_IGN);
/***************************************************
2.生成第一个子进程,确保能够正确产生新的会话期
*****************************************************/
a = fork();
if(a > 0)
{
exit(0);
}
/***************************************************
3.调用setsid()函数,让第一个子进程产生新的没有控制终端的会话期
*****************************************************/
setsid();
/***************************************************
4.生成第二个子进程,防止精灵进程打开终端文件创建控制终端
*****************************************************/
a = fork();
if(a > 0)
{
exit(0);
}
/***************************************************
5.分离精灵进程的原生进程组,防止接收到任何控制进程组的信号
*****************************************************/
setpgrp();
/***************************************************
6.关闭所有的文件描述符,释放资源
*****************************************************/
max_fd = sysconf(_SC_OPEN_MAX);
for(i = 0; i < max_fd; i++)
{
close(i);
}
/***************************************************
7.文件权限掩码清零
*****************************************************/
umask(0);
/***************************************************
8.改变进程的工作路径,确保进程不会被卸载
*****************************************************/
chdir("/");
/***************************************************
9.精灵进程创建成功
*****************************************************/
//精灵进程要干的事
my_log("精灵进程启动\n");
sumu();
pause();
return 0;
}
void sumu(void)
{
//signal(SIGINT,SIG_IGN);//捕捉ctrl+c信号
key_t key =ftok(MEM_PATH,1);
//create shm
int shmid=shmget(key,1024,IPC_CREAT|0666);
if(-1==shmid)
{
perror("shmget erro");
exit(1);
}
//create 2 sem
int semid=semget(key,2,IPC_CREAT|0666);
if(-1==semid)
{
perror("semget erro");
exit(1);
}
//init sem
shm_init(semid,SPACE,1);//space设置信号量0为1
shm_init(semid,DATA,0);//data设置信号量1为0
char *p=shmat(shmid,NULL,0);
if(NULL==p)
{
perror("shmat erro");
exit(1);
}
printf("recv start\n");
while(1)
{
P(semid,DATA);
printf("recv:%s",p);
my_log(p);
V(semid,SPACE);
if(!strncmp(p,"quit",4))
{
break;
}
}
shmdt(p);
return ;
}
void shm_init(int id,int num,int val)
{
union semun a;
a.val=val;
semctl(id,num,SETVAL,a);
}
void P(int id,int num)
{
struct sembuf sops[1];
sops[0].sem_num=num;//信号量元素编号
sops[0].sem_op=-1;//P操作
sops[0].sem_flg=0;//0表示阻塞
semop(id,sops,1);//执行P操作
}
void V(int id,int num)
{
struct sembuf sops[1];
sops[0].sem_num=num;//信号量元素编号
sops[0].sem_op=1;//V操作
sops[0].sem_flg=0;//0表示阻塞
semop(id,sops,1);//执行V操作
}
void my_log(char *str)
{
int fd = open("/mnt/share/project/project_01/log.txt",O_CREAT|O_RDWR|O_APPEND);
if(-1 == fd)
{
perror("open erro");
return;
}
write(fd,str,strlen(str));
close(fd);
}
app函数(用户函数)
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <signal.h>
#include <sys/shm.h>
#include <time.h>
#define SPACE 0
#define DATA 1
#define MEM_PATH "/mnt/share/project/project_01/"
void shm_init(int id,int num,int val);
void P(int id,int num);
void V(int id,int num);
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
struct sembuf sops;
int main(int argc,char const *argv[])
{
signal(SIGINT,SIG_DFL);//捕捉ctrl+c信号,恢复默认信号处理函数
key_t key =ftok(MEM_PATH,1);
//create shm
int shmid=shmget(key,1024,IPC_CREAT|0666);
if(-1==shmid)
{
perror("shmget erro");
exit(1);
}
//create 2 sem
int semid=semget(key,2,IPC_CREAT|0666);
if(-1==semid)
{
perror("semget erro");
exit(1);
}
//init sem
shm_init(semid,SPACE,1);//space设置信号量0为1
shm_init(semid,DATA,0);//data设置信号量1为0
char *p=shmat(shmid,NULL,0);//将shm映射到进程空间
if(NULL==p)
{
perror("shmat erro");
exit(1);
}
//获取日志的信息
int pid = getpid();
time_t now;
time(&now);
while (1)
{
memset(p,0,1024);
P(semid,SPACE);//空间-1
// printf("please input:");
// fgets(p,1024,stdin);
sprintf(p,"pid=%d,time=%s",pid,ctime(&now));
V(semid,DATA);//数据+1
if(!strncmp(p,"quit",4))
{
break;
}
//添加延迟
usleep(1000000);
}
shmdt(p);
return 0;
}
void shm_init(int id,int num,int val)
{
union semun a;
a.val=val;
semctl(id,num,SETVAL,a);
}
void P(int id,int num)
{
struct sembuf sops[1];
sops[0].sem_num=num;//信号量元素编号
sops[0].sem_op=-1;//P操作
sops[0].sem_flg=0;//0表示阻塞
semop(id,sops,1);//执行P操作
}
void V(int id,int num)
{
struct sembuf sops[1];
sops[0].sem_num=num;//信号量元素编号
sops[0].sem_op=1;//V操作
sops[0].sem_flg=0;//0表示阻塞
semop(id,sops,1);//执行V操作
}
日志文件
结果图