信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程
函数原型:
int kill(pid_t pid, int sig);
函数参数:
pid:
正数:要接收信号的进程的进程号
0:信号被发送到所有和pid进程在同一个进程组的进程
-1:信号发给所有的进程表中的进程(除了进程号最大的进程外)
sig:信号
返回值:成功返回0,失败返回-1
SIGKILL:杀死进程
SIGALRM:定时
SIGSTOP:停止进程
SIGCHLD:子进程改变状态时,父进程会收到这个信号
SIGQUIT:退出进程
SIGCONT:继续执行进程
函数原型:
int raise(int sig);
函数参数:
sig:信号
返回值:成功返回0,失败返回-1
void (*signal(int signum, void (*handler)(int)))(int);
函数原型:
unsigned int alarm(unsigned int seconds);
函数参数:
seconds:定时时长
返回值:如果调用函数之前已经存在一个定时器会返回定时器剩余时间
函数原型:
int pause(void);
Pause()使调用进程(或线程)休眠,直到传递信号,该信号要么终止进程,要么导致调用信号捕获函数。
函数原型:
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
函数参数:
signum:指定的信号
handler:
SIG_IGN:忽略该信号。
SIG_DFL:采用系统默认方式处理信号。
自定义的信号处理函数指针
返回值:设置之前的信号处理方式,出错-1
为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间,共享内存是一种最高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝
共享内存的使用包括如下步骤:
获取IPC对象key ftok
创建/打开共享内存 shmget
映射共享内存 shmat
撤销共享内存映射 shmdt
删除共享内存对象 shmctl
函数原型:
key_t ftok(const char *pathname,int proj_id);
函数参数:
pathname:文件路径名
proj_id:子序号
返回值:成功返回生成的KEY,失败返回-1
函数原型:
int shmget(key_t key,int size,int shmflg);
函数参数:
key:IPC_PRIVATE或ftok的返回值
size:共享内存区大小,4096为数据块单位大小
shmflg:权限位,如包含IPC_CREAT,则新建一个对象
返回值:成功返回共享内存段标识符,失败返回-1
函数原型:
void *shmat(int shmid,const void *shmaddr,int shmflg);
函数参数:
shmid:要映射的共享内存区标识符
shmaddr:将共享内存映射到指定地址,NULL,则表示由系统自动完成映射
shmflg:
SHM_RDONLY:共享内存只读
0:可读可写
返回值:成功返回映射后的地址,失败返回-1
函数原型:
int shmdt(const void *shmaddr);
函数参数:
shmaddr:共享内存映射后的地址
返回值:成功返回0,失败返回-1
函数原型:
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
函数参数:
shmid:共享内存区标识符
cmd:
IPC_STAT (获取对象属性)
IPC_SET (设置对象属性)
IPC_RMID (删除对象)
buf:对象属性指针,删除时填NULL
返回值:成功返回0,失败返回-1
消息队列的使用包括如下步骤:
获取IPC对象key ftok
创建/打开消息队列 msgget
添加数据到队列中 msgsnd
从队列中获取数据 msgrcv
删除共享消息队列 msgctl
函数原型:
int msgget(key_t key, int msgflg);
函数参数:
key:IPC_PRIVATE或ftok的返回值
msgflg:权限位,如包含IPC_CREAT,则新建一个对象
返回值:成功返回消息队列ID,失败返回-1
函数原型:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
函数参数:
msqid:消息队列ID
msgp:消息指针
msgsz:消息正文大小常用消息结构msgbuf如下:
struct msgbuf{
long mtype; //消息类型
char mtext[N]; //消息正文
};
msgflg:
IPC_NOWAIT:消息没有发送完成函数也会立即返回
0:阻塞直到发送完成函数才返回
返回值:成功返回0,失败返回-1
函数原型:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
函数参数:
msqid:消息队列ID
msgp:接收消息指针
msgsz:消息正文大小常用消息结构msgbuf如下:
struct msgbuf{
long mtype; //消息类型
char mtext[N]; //消息正文
};
msgtyp:
0:接收消息队列中第一个消息。
>0:接收消息队列中第一个类型为msgtyp的消息
<0:接收消息队列中类型值不小于msgtyp的绝对值且类型值又最小的消息
msgflg:
IPC_NOWAIT:若没有消息,进程会立即返回ENOMSG
0:阻塞直到接收完成函数才返回
返回值:成功返回接收到的消息的长度,失败返回-1
函数原型:
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
函数参数:
msqid:消息队列ID
cmd:
IPC_STAT (获取对象属性)
IPC_SET (设置对象属性)
IPC_RMID (删除对象)
buf:对象属性指针,删除时填NULL
返回值:成功返回0,失败返回-1
信号灯(semaphore),也叫信号量,是不同进程间或一个给定进程内部不同线程间同步的机制。
二值信号灯:值为0或1。与互斥锁类似,资源可用时值为1,不可用时值为0。
计数信号灯:值在0到n之间。用来统计资源,其值代表可用资源数
信号灯的使用包括如下步骤:
获取IPC对象key ftok
创建/打开信号灯 semget
信号灯初始化 semctl
P/V申请释放资源 semop
删除信号灯 semctl
函数原型:
int semget(key_t key,int nsems,int semflg);
函数参数:
key:IPC_PRIVATE或ftok的返回值
nsems:信号灯个数
semflg:权限位,如包含IPC_CREAT,则新建一个对象
返回值:成功返回信号灯集ID,失败返回-1
函数原型:
int semop(int semid,struct sembuf *opsptr,size_t nops);
函数参数:
semid:信号灯集ID
opsptr:信号灯操作
struct sembuf{
short sem_num; // 要操作的信号灯的编号
short sem_op; // 0 : 等待,直到信号灯的值变成0
// 1 : 释放资源,V操作
// -1 : 分配资源,P操作
short sem_flg; // 0, IPC_NOWAIT, SEM_UNDO
};
nops:信号灯数目
返回值:成功返回0,失败返回-1
函数原型:
int semctl(int semid,int semnum,int cmd,.../*union semun arg*/);
函数参数:
semid:信号灯集ID
semnum:要修改的信号灯编号
cmd:
GETVAL:获取信号灯的值
SETVAL:设置信号灯的值
IPC_RMID:从系统中删除信号灯集合
arg:设置属性
union semun{
int val;//Value for SETVAL
struct semid_ds *buf;
unsigned short *arrar;
struct seminfo *_buf;
}
返回值:成功返回0,失败返回-1