进程间的通信

-----------------------------------------------------守护进程的创建-------------------------------------------------------

------------------------------守护进程(后台进程)的创建------------------------------------
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<syslog.h>
#include<sys/types.h>
#include<unistd.h>


void demon_init(void);


int main(int argc, char const *argv[])
{

	demon_init();
	//打开日志
	openlog("qxjpmm",LOG_PID,LOG_DAEMON);

	int fd = open("xx.txt",O_RDWR|O_TRUNC);

	if (fd < 0){
		
		syslog(LOG_ERR,"open error");
		exit(-1);
	}
	char buf[20] = "qxj5683pmm";

	while(1){

		sleep(1);

		write(fd,buf,strlen(buf));
		syslog(LOG_INFO,"%s",buf);

	}

	closelog();
	close(fd);

	return 0;
}


void demon_init(void){

	//创建子进程2,结束父进程1
	if (fork() != 0){
		exit(0);
	}
	//创建会话
	if (setsid() < 0){

		perror("setsid error");
		exit(-1);
	}

	//创建子进程3,结束父进程2
	if (fork() != 0){
		exit(0);
	}

	//关闭所有的文件描述符

	for (int i = 0; i <= sysconf(_SC_OPEN_MAX); i++){
		
		close(i);
	}

	//改变执行目录----->将执行目录换到根目录

	chdir("/");

	//修改掩码---->将掩码修改为0  系统默认0002;
	umask(0);

	//将标准输入,标准输出,标准错误输出全部重定向到null
	int fd = open("/dev/null",O_RDWR);

	dup(0);
	dup(0);
}

----------------------------------------------------进程间的通信方式-----------------------------------------------------

-1>无名管道

        主要用途子父进程间的通信

        

无名管道的API--------->int pipe(int pipefd[2])
        头文件:   #include <unistd.h>

    int pipe(int pipefd[2]);
					功能:
								创建无名管道
					参数:
							pipefd[2]:数组	保存 读写 文件描述符
											[0]--->读
											[1]--->写
					
					返回值:
							成功返回0;
							失败返回-1,并返回错误码
							
					例如:
						int pipefd[2];
						int ret = pipe(pipefd);
						if(ret < 0){
							......
						}
						pid_t pid = fork();
						if(pid == 0){
							关闭写功能
							close(pipefd[1])
							char buf[128];
							
							while(1){
								读
							}
						}
						
						if(pid > 0){
							关闭读功能
							close(pipefd[0])
							char buf[128];
							while(1){
								写
							}
						}

-2>有名管道

        适用于任何进程间的通信

有名管道的API------> int mkfifo(const char *pathname, mode_t mode)
            头文件:#include <sys/types.h>
					#include <sys/stat.h>
            功能:
							创建有名管道
							
					参数:
							pathname:管道文件的名字(带路径)
							mode:权限:0666
							
					返回值:成功返回0;
					失败返回-1,并返回错误码

           判断某文件是否拥有某功能的API----> int access(const char *pathname, int mode);
					头文件:#include <unistd.h>
					
					功能:
							判断某文件是否拥有某功能
							
					参数:
							pathname:管道文件的名字(带路径

							mode:
									F_OK:---》文件存在
									R_OK:---》文件可读
									W_OK:---》文件可写
									X_OK:---》文件可执行
									
					返回值:成功返回0;
							失败返回-1,并返回错误码

-3>信号

        信号是软件层面上对中断机制的一种模拟,是一种异步的通信
        信号可以直接进行用户空间进程和内核进程之间的交互。

信号的注册API------>  sighandler_t signal(int signum, sighandler_t handler);
		
	头文件:	#include <sys/types.h>
            #include <signal.h>

       typedef void (*sighandler_t)(int);
       
		功能:
				信号的注册
				
		参数:
				signum:信号
				handler:事件
					SIG_IGN:忽略
					SIG_DFL:默认
					捕捉:执行某一个 自定义 的事件 void(*)(int)
					
		返回值:
				成功返回sighandler_t
				失败返回SIG_ERR并返回错误码


信号的发送API-----------> int kill(pid_t pid, int sig);
    功能:
				发送信号
		参数:
				pid:进程的pid号(给谁发)
				sig:信号
		返回值:
				成功返回0
				失败返回-1,并返回错误码

-4>共享内存

        是进程间的通信最快的一种

共享内存的相关API
			1>创建或者获取共享内存API--->int shmget(key_t key, size_t size, int shmflg);
			
			头文件:#include <sys/ipc.h>
			        #include <sys/shm.h>
			
			功能:创建或者获取共享内存
			
			参数:key:密钥
					获取key:
							1>IPC_PRIVATE  0 系统自动分配
									--->不断生成新的共享内存		
							2>手动

							ftok()的头文件:#include <sys/types.h>
							                #include <sys/ipc.h>

							key_t ftok(const char *pathname, int proj_id);
							功能:创建key
							参数:
									pathname:文件名字(带路径)
									proj_id:数字
							返回值:
									成功返回key
									失败返回-1,并返回错误码
									
							注意!!!:
								只要pathname和proj_id不变,就可以获得相同的key
								例子:
									进程A:key_t key1=ftok("xx.txt",5);
									进程B:key_t key2=ftok("xx.txt",5);
									那么进程A和进程B都可以获得到相同的key
									
					size:共享内存的大小
					shmflg:IPC_CREAT|0666
					
			返回值:
					成功返回shmid
					失败返回-1,并返回错误码
					
		2>将共享内存映射到用户空间API---->void *shmat(int shmid, const void *shmaddr, int shmflg);
			
				头文件:#include <sys/types.h>
				        #include <sys/shm.h>
				
				功能:
						将共享内存映射到用户空间
				参数:
						shmid:共享内存ID
						shmaddr:你想映射的地方(地址)
						shmflg:0 可读可写
						
				返回值:
					成功返回地址
					失败返回-1,并返回错误码
					
					
		3>解除映射API---->int shmdt(const void *shmaddr);
			
		头文件: #include <sys/types.h>
		         #include <sys/shm.h>
		 
		 功能:
				解除映射
		 参数:
				shmaddr:映射地址
				
		 返回值:
				成功返回0
				失败返回-1,并返回错误码
				
		4>删除共享内存API---->  int shmctl(int shmid, int cmd, struct shmid_ds *buf);
			
		头文件: #include <sys/ipc.h>
                 #include <sys/shm.h>
        
		 功能:
				对共享内存进行控制
		 参数:
				shmid:共享内存ID
				cmd:IPC_RMID :移除共享内存
				buf:IPC_RMID:NULL
				
		 返回值:
				IPC_RMID
				成功返回0
				失败返回-1,并返回错误码

-5>信号量/信号灯(临界资源)

        在系统V 的信号灯是一个或多个信号灯的集合。其中每一个都是单独的计数信号灯

3>信号灯的相关API(接口)
			1>创建或获取信号量API---->int semget(key_t key,int nsems,int semflg)
				
			头文件:	#include <sys/types.h>
				    #include <sys/ipc.h>
				    #include <sys/sem.h>
				
				功能:
						创建或获取信号量
				参数:
						key:密钥
						nsems:信号灯/信号量的个数
						semflg:IPC_CREAT|0666
						
				返回值:成功返回semid
						失败返回-1,并返回错误码
						
			2>对信号灯进行PV操作API(P为减法,V为加法)----->int semop(int semid,struct sembuf *sops,size_t nsops)
				
				头文件:#include <sys/types.h>
				        #include <sys/ipc.h>
				        #include <sys/sem.h>
				功能:
						对信号灯进行操作
				参数:
						semid:semget返回的semid值
						sops:结构体指针(数组)

					    struct sembuf{

					    nsigned short sem_num;  /* semaphore number */ 信号灯的下标
					    short          sem_op;   /* semaphore operation */操作:+1 +2 -1            -2... PV操作
					    short          sem_flg;  /* operation flags */0 可阻塞 IPC_NOWAIT不阻塞
						}
						nsops:数组中元素的个数

				返回值:
						成功返回0
						失败返回-1
						
						
				3>删除(控制)信号量API----->int semctl(int semid,int semnum,int cmd, ...)
					
				头文件: #include <sys/types.h>
				 #include <sys/ipc.h>
				 #include <sys/sem.h>
				 功能:
						删除(控制)信号量
				 参数:
						semid:semget返回的semid值	
						semnum:信号量的下标
						cmd:
								IPC_RMID:删除信号量
								GETVAL:获取到信号灯的value值
								SETVAL:设置信号灯的value值
								GETALL:获取多个信号灯的value值
								SETALL:设置多个信号灯的value值
						如果cmd不是IPC_RMID,则有第四个参数:这个参数是联合体
			union semun {
               int              val;    /* Value for SETVAL */ 设置某个信号灯的值
               struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
               unsigned short  *array;  /* Array for GETALL, SETALL */ 设置或获取多个信号灯的值
               struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                           (Linux-specific) */
           };

				 返回值:
						GETVAL:成功返回value值
						其他成功返回0
						失败返回-1,并返回错误码

-6>socket套接字(后续在网络编程更新)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值