linux多进程&多进程通信IPC

###pid_t getpid(void);
	取得目前进程的进程识别码

###pid_t getppid(void);
	取得目前进程的父进程识别码

### pid_t getpgid( pid_t pid);
	取得参数 pid 指定进程所属的组识别码 如果参数pid 为 0,则会取得目前进程的组识别码

###int setuid(uid_t uid);
	重新设置执行目前进程的用户识别码

###pid_t getsid(pid_t pid);
	 返回调用进程的会话ID

###pid_t setsid(void);
	进程从它的双亲进程获得它的对话过程和进程组识别号
	setsid()就是将进程和它当前的对话过程和进程组分离开,并且把它设置成一个新的对话过程的领头进程。

###pid_t tcgetsid(int filedes);
	返回值:成功返回会话首进程的进程组ID,出错返回-1。

###pid_t tcgetpgrp(int filedes);
	返回值:成功返回前台进程组的进程组ID,出错返回-1

###mode_t umask(mode_t mask);
	设置建立新文件时的权限遮罩

###pid_t wait (int * status);
	wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。
	如果在调用 wait()时子进程已经结束,则 wait()会立即返回子进程结束状态值。

	status 返回子进程的结束状态值
		WIFEXITED(status)		如果子进程正常结束则为非 0 值。
		WEXITSTATUS(status)		取得子进程 exit()返回的结束代码
		WIFSIGNALED(status)	如果子进程是因为信号而结束则此宏值为真 
		TERMSIG(status)			取得子进程因信号而中止的信号代码
		WIFSTOPPED(status) 	如果子进程处于暂停执行情况则此宏值为真
		WSTOPSIG(status) 			取得引发子进程暂停的信号代码

	返回值 成功返回子进程识别码,失败返回-1 失败原因存于 errno 中

#执行文件

###int execl(const char *path, const char *arg, ...);	
	path	文件目录
	arg		argv[0],argv[1],...,NULL
		execl("/bin/ls","ls","-a",”/etc/passwd”,(char *)0);
	失败返回 -1 error

###int execlp(const char *file, const char *arg, ...);
	从 PATH 环境变量所指的目录中查找符合参数 file 的文件名,找到后便执行该文件
	execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);

###int execle(const char *path, const char *arg,..., char * const envp[]);
	结合上下文,这个函数看不懂就可以去死了

###int execv(const char *path, char *const argv[]);
	char * argv[]={“ls”,”-al”,”/etc/passwd”,(char*) 0};
	execv(“/bin/ls”,argv);

###int execvp(const char *file, char *const argv[]);
	char * argv[ ] ={ “ls”,”-al”,”/etc/passwd”,0};
	execvp(“ls”,argv);

###int execve(const char *file, char *const argv[],char *const envp[]);
	char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char *)0};
	char * envp[ ]={“PATH=/bin”,0}
	execve(“/bin/ls”,argv,envp);
	


#### 使用系统守护进程,实现授时服务器
	vi /etc/xinetd.d/
	service date_mine
	{
		disable		= no		禁止远方telnet,假如需要开放则将该配置改为:disable=no
		type		= UNLISTED
		socket_type	= stream
		protocol	= tcp
		user		= chandler
		wait		= no		不等待到启动完成
		port 		= 5859
		bind		= 127.0.0.1
		server		= /bin/date
	}
	service xinetd start
	service xinetd restart

#多进程通信IPC
---
###int dup2(int odlfd,int newfd);
	把newfd关闭,然后复制到odlfd
##管道
###int pipe(int filedes[2]);
	创建管道

###int mkfifo(const char * pathname,mode_t mode);
	res = mkfifo(FIFO_NAME, 0766);
	int ret = mkfifo(_PATH_,0666|S_IFIFO);
	若成功则返回 0,否则返回-1,错误原因存于 errno 中。


##消息队列
	struct ipc_perm
	{
		__kernel_key_t	key;   
		__kernel_uid_t	uid;
		__kernel_gid_t	gid;
		__kernel_uid_t	cuid;
		__kernel_gid_t	cgid;
		__kernel_mode_t	 mode; 
		unsigned short	seq;
	};
	struct msqid_ds {
		   struct ipc_perm msg_perm;     /* Ownership and permissions */
		   time_t          msg_stime;    /* Time of last msgsnd(2) */
		   time_t          msg_rtime;    /* Time of last msgrcv(2) */
		   time_t          msg_ctime;    /* Time of last change */
		   unsigned long   __msg_cbytes; /* Current number of bytes in
		                                    queue (nonstandard) */
		   msgqnum_t       msg_qnum;     /* Current number of messages
		                                    in queue */
		   msglen_t        msg_qbytes;   /* Maximum number of bytes
		                                    allowed in queue */
		   pid_t           msg_lspid;    /* PID of last msgsnd(2) */
		   pid_t           msg_lrpid;    /* PID of last msgrcv(2) */
		   struct msg *    msq_first ;
	 	   struct msg *    msq_last ;
	};


###key_t ftok(const char *pathname, int proj_id);
	pathname 文件路径名
	proj_id 一个数字
	返回值,key
	 printf("\nket=0x%08x\n\nproj_id=0x%02x\nst_dev=0x%02x\nst_ino0x=%04x\n",
			 key,key>>24,(key<<8)>>24,(key<<16)>>16);


* 创建对象
###int msgget(key_t key, int msgflg);
	if((msgid=msgget(key,0600|IPC_CREAT))==-1)

	int msgflg 确定消息队列的访问权限,	
		IPC_CREAT  找到当前的key对应的IPC,如果没有IPC则进行创建
		IPC_EXCL   如果存在则返回失败
		IPC_NOWAIT 
	返回值为当前ipc对应的id值 

* 设置对象:
###int msgctl(int msqid,int cmd,struct msqid_ds *buf);
	cmd:
		IPC_RMID  删除 
		IPC_SET  设置ipc_perm参数 
		IPC_STAT 获取ipc_perm参数
		IPC_INFO 获取ipc信息  和ipcs
* 使用对象:
1. 发送
###int msgsnd(int msqid,const void *msg_ptr,size_t sz,int msgflg);
    struct msgbuf 
	{
       long int mtype;   id
       char* text;    	 数据指针
    };
	sz:		要发送消息的大小,不含消息类型占用的4个字节,即mtext的长度

	msgflg:
		0:当消息队列满时,msgsnd将会阻塞,直到消息能写进消息队列
		IPC_NOWAIT:当消息队列已满的时候,msgsnd函数不等待立即返回
		IPC_NOERROR:若发送的消息大于size字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。

2. 接收    
###ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
	msgtyp 0   默认接收第一条消息 
	msgtyp > 0 接收第一条msgtyp消息
	msgtyp < 0 接收小于msgtyp绝对值的消息

## XSI信号量
	struct semid_ds {
		struct ipc_perm sem_perm;  /* Ownership and permissions */
		time_t          sem_otime; /* Last semop time */
		time_t          sem_ctime; /* Last change time */
		unsigned long   sem_nsems; /* No. of semaphores in set */
		struct   sem *	sem_base 
	};
	struct sem{
		int semval  信号量的值
		int sempid  最近一个操作的进程号
	}

#### 概念:
* 实现进程间同步
* 表示系统可用资源的个数

#### 对象操作
* 创建对象: 
###int  semget(key_t _key ,int _nsems,int _semflg);
		semid=semget(MYKEY,1,IPC_CREAT|0666);//创建了一个权限为666的信号量

	功能:创建一个新的信号量或获取一个已经存在的信号量的键值。
	返回值:成功返回信号量的标识码ID。失败返回-1;
	
	参数:
	_key  为整型值,用户可以自己设定。有两种情况:
		1.键值是IPC_PRIVATE,该值通常为0,意思就是创建一个仅能被进程进程给我的信号量。
		2.键值不是IPC_PRIVATE,我们可以指定键值,例如1234;也可以一个ftok()函数来取得一个唯一的键值。

	_nsems 表示初始化信号量的个数。比如我们要创建一个信号量,则该值为1.,创建2个就是2。

	_semflg  :信号量的创建方式或权限。有IPC_CREAT,IPC_EXCL。
		IPC_CREAT如果信号量不存在,则创建一个信号量,否则获取。
		IPC_EXCL只有信号量不存在的时候,新的信号量才建立,否则就产生错误。


* 设置对象:
###int  semctl(int _semid  ,int _semnum,int _cmd  ……);
	功能:控制信号量的信息。
	返回值:成功返回(谁他娘知道成功返回什么玩意啊),失败返回-1;
	
	参数:
	_semid   信号量的标志码(ID),也就是semget()函数的返回值;
	
	_semnum,  操作信号在信号集中的编号。从0开始。
	
	_cmd    命令,表示要进行的操作。
		IPC_STAT		读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
		IPC_SET			设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
		IPC_RMID		将信号量集从内存中删除。
		GETALL			用于读取信号量集中的所有信号量的值。
		GETNCNT			返回正在等待资源的进程数目。
		GETPID			返回最后一个执行semop操作的进程的PID。
		GETVAL			返回信号量集中的一个单个的信号量的值。(return出来)
		GETZCNT			返回这在等待完全空闲的资源的进程数目。
		SETALL			设置信号量集中的所有的信号量的值。
		SETVAL			设置信号量集中的一个单独的信号量的值。
	
	第4个参数是可选的;semunion :是union semun的实例。
	union semun {
	   int  			val;
	   struct semid_ds  *buf;
	   unsigned short   *arrary;
	};


###int semop(int semid,struct sembuf *_sops ,size_t _nsops);
	功能:用户改变信号量的值。也就是使用资源还是释放资源使用权。
	
	返回值:成功返回0,失败返回-1;
	
	参数:	
	_semid : 信号量的标识码	
	_sops是一个指向结构体数组的指针。	
		 struct   sembuf{	
		     unsigned short  sem_num;	
		     short  sem_op;				
		     short _semflg;	
		}; 			
			sem_num:  操作信号在信号集中的编号。第一个信号的编号为0;
			sem_op : 如果其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。
			_semflg:
					SEM_NOWAIT 	//对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。
					SEM_UNDO 	//程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。 
	
	nsops:操作结构的数量,恒大于或等于1。


##XSI共享内存

* 数据量最大
* 传输最快
* mmap 

#### 共享内存对象

	struct shmid_ds {
		struct ipc_perm		shm_perm;	/* operation perms */
		int	  shm_segsz;	/* size of segment (bytes) */
		__kernel_time_t		shm_atime;	/* last attach time */
		__kernel_time_t		shm_dtime;	/* last detach time */
		__kernel_time_t		shm_ctime;	/* last change time */
		__kernel_ipc_pid_t	shm_cpid;	/* pid of creator */
		__kernel_ipc_pid_t	shm_lpid;	/* pid of last operator */
		unsigned short		shm_nattch;	/* no. of current attaches */
		unsigned short 		shm_unused;	/* compatibility */
		void 			*shm_unused2;	/* ditto - used by DIPC */
		void			*shm_unused3;	/* unused */
	}
	
	struct shm_info {
	 int           used_ids; /* # of currently existing
	                            segments */
	 unsigned long shm_tot;  /* Total number of shared
	                            memory pages */
	 unsigned long shm_rss;  /* # of resident shared
	                            memory pages */
	 unsigned long shm_swp;  /* # of swapped shared
	                            memory pages */
	 unsigned long swap_attempts;
	                         /* Unused since Linux 2.4 */
	 unsigned long swap_successes;
	                         /* Unused since Linux 2.4 */
	};



* 创建共享内存
###int shmget(key_t key, size_t size, int shmflg);
	size是要建立共享内存的长度。所有的内存分配操作都是以页为单位的

* 设置共享内存
###int shmctl(int shmid, int cmd, struct shmid_ds *buf);

	IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值,即用共享内存的当前关联值覆盖shmid_ds的值。
	IPC_SET:如果进程有足够的权限,就把共享内存的当前关联值设置为shmid_ds结构中给出的值
	IPC_RMID:删除共享内存段
	
	shmid_ds结构 至少包括以下成员:
	
	struct shmid_ds
	{
	    uid_t shm_perm.uid;
	    uid_t shm_perm.gid;
	    mode_t shm_perm.mode;
	};


* 使用对象
###void *shmat(int shmid, const void *shmaddr, int shmflg);
	shmat()将由shmid标识的System V共享内存段附加到调用进程的地址空间。
	附加地址由shmaddr使用以下标准之一指定:
		shmaddr为NULL,系统将选择一个合适的(未使用的)地址来附加该段。
		shmaddr不是NULL并且在shmflg中指定了
	shmflg:
		SHM_RDONLY			附加段以进行只读访问。该流程必须具有该段的读取权限
		SHM_REMAP			此标志指定段的映射应替换从shmaddr开始并继续执行段大小的任何现有映射
		SHM_EXEC			允许执行段的内容。调用者必须具有该段的执行权限

##int shmdt(const void *shmaddr);
	解除共享内存的使用
	shmaddr 共享内存的指针


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值