signal
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void fa(int signo){
printf("捕获了信号%d\n",signo);
alarm(1);//新闹钟,实现循环的效果
}
int main(){
signal(SIGALRM,fa);
alarm(5);
sleep(3);
int res = alarm(5);
printf("res=%d\n",res);
//alarm(0);//取消所有闹钟
while(1);
}
信号列表查看 http://www.2cto.com/os/201202/119425.html
kill
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void fa(int signo){
printf("捕获了信号%d\n",signo);
}
int main(){
//signal(SIGINT,fa);//父进程执行,子进程继承
pid_t pid = fork();
//signal(SIGINT,fa);//父子进程分别执行
if(pid == 0){
signal(SIGINT,fa);
printf("pid=%d\n",getpid());
while(1);
}
usleep(10);
kill(pid,SIGINT);
printf("信号已经发送完毕\n");
return 0;
}
raise
#include <stdio.h>
#include <signal.h>
void fa(int signo){
printf("捕获了信号%d\n",signo);
}
int main(){
signal(SIGINT,fa);
int res = sleep(10);//会被信号打断,返回剩余秒数
printf("res=%d\n",res);
raise(SIGINT);//给自己发了信号2
while(1);
}
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void fa(int signo){
printf("捕获了信号%d\n",signo);
}
int main(){
signal(SIGINT,fa); // 信号2自定义
signal(SIGQUIT,SIG_IGN);//信号3被忽略
pid_t pid = fork();
if(pid == 0){//fork()的子进程信号处理与父进程一样
printf("pid=%d\n",getpid());
while(1);
}
printf("父进程结束\n");
return 0;
}
sigprocmask
#include <stdio.h>
#include <signal.h>
void fa(int signo){
printf("捕获到了信号%d\n",signo);
}
int main(){
signal(SIGINT,fa); signal(SIGQUIT,fa);
signal(50,fa);
printf("pid=%d\n",getpid());
printf("执行普通代码,没有屏蔽信号\n");
sleep(15);
printf("执行关键代码,开始信号屏蔽\n");
sigset_t set,old;//set屏蔽,old解除
sigemptyset(&set); sigaddset(&set,50);
sigaddset(&set,2); sigaddset(&set,3);
sigprocmask(SIG_SETMASK,&set,&old);//开始屏蔽
sleep(15); printf("屏蔽被解除\n");
sigprocmask(SIG_SETMASK,&old,0);//解除屏蔽
}//50是可靠信号,所以不丢失;2 3是不可靠信号 会丢失
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void fa(int signo){
printf("捕获了信号%d\n",signo);
}
int main(){
signal(SIGINT,fa); // 信号2自定义
signal(SIGQUIT,SIG_IGN);//信号3被忽略
pid_t pid = vfork();
if(pid == 0){
printf("pid=%d\n",getpid());
execl("./proc","proc",NULL);
}
printf("父进程结束\n");
return 0;
}
计时器
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
void fa(int signo){
printf("每隔1.1秒执行一次\n");
}
int main(){
signal(SIGALRM,fa);
struct itimerval timer;
//间隔时间
timer.it_interval.tv_sec = 1;//秒数
timer.it_interval.tv_usec = 100000;//微秒
//开始时间
timer.it_value.tv_sec = 5;
timer.it_value.tv_usec = 0;
setitimer(ITIMER_REAL,&timer,0);//启动计时器
while(1);
}
消息队列
IPC结构的相关命令:
ipcs 查看IPC结构
-a 显示所有的IPC结构
-m 显示 共享内存
-q 显示 消息队列
-s 显示 信号量集
ipcrm 删除IPC结构
选项和ipcs 基本一样,但在选项后需要加上IPC结构的ID。
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
struct MSG{
long mtype;
char buf[256];
};
int main(){
key_t key = ftok(".",100);
int msgid = msgget(key,0666|IPC_CREAT);
if(msgid == -1) perror("msgget"),exit(-1);
struct MSG msg1,msg2;
msg1.mtype = 1; strcpy(msg1.buf,"zhangfei");
msg2.mtype = 2; strcpy(msg2.buf,"guanyu");
int res = msgsnd(msgid,&msg1,sizeof(msg1.buf),0);
if(res == -1) perror("msgsnd msg1"),exit(-1);
res = msgsnd(msgid,&msg2,sizeof(msg2.buf),0);
if(res == -1) perror("msgsnd msg2"),exit(-1);
printf("发送成功\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>
struct MSG{
long mtype;
char buf[256];
};
int main(){
key_t key = ftok(".",100);
int msgid = msgget(key,0);
if(msgid == -1) perror("msgget"),exit(-1);
struct MSG msg1;
int res=msgrcv(msgid,&msg1,sizeof(msg1.buf),-2,0);
if(res == -1) perror("msgsnd msg1"),exit(-1);
printf("%s\n",msg1.buf);
return 0;
}
ipc共享内存
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
key_t key = ftok(".",100);//创建key,路径只要存在
if(key == -1) perror("ftok"),exit(-1);//key就没错
int shmid = shmget(key,4,0666|IPC_CREAT|IPC_EXCL);
if(shmid == -1) perror("shmget"),exit(-1);
printf("共享内存创建成功\n");
void* p = shmat(shmid,0,0);//挂接
if(p == (void*)-1) perror("shmat"),exit(-1);
int* pi = p;
*pi = 100;//存入共享内存
shmdt(p);//脱接
return 0;
}//练习:写shmb.c,把100从共享内存中取出并打印
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
key_t key = ftok(".",100);//创建key,路径只要存在
if(key == -1) perror("ftok"),exit(-1);//key就没错
int shmid = shmget(key,0,0);
if(shmid == -1) perror("shmget"),exit(-1);
void* p = shmat(shmid,0,0);//挂接
if(p == (void*)-1) perror("shmat"),exit(-1);
printf("%d\n",*(int*)p);
shmdt(p);//脱接
return 0;
}
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
key_t key = ftok(".",100);
int shmid = shmget(key,0,0);
if(shmid == -1) perror("shmget"),exit(-1);
struct shmid_ds ds;
shmctl(shmid,IPC_STAT,&ds);//查询
printf("key=%x,%x\n",key,ds.shm_perm.__key);
printf("size=%d\n",ds.shm_segsz);
printf("mode=%o\n",ds.shm_perm.mode);
printf("nattch=%d\n",ds.shm_nattch);
ds.shm_perm.mode = 0600;//准备修改,权限能改
ds.shm_segsz = 400;//大小不能改
shmctl(shmid,IPC_SET,&ds);//修改共享内存
//shmctl(shmid,IPC_RMID,0);//删除共享内存
return 0;
}
信号量
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
int semid;//全局变量,两个函数都可以使用
void fa(int signo){//3
printf("服务器即将关闭\n");
semctl(semid,0,IPC_RMID);//删除信号量集
exit(0);
}
int main(){//只是建了一个计数器的数组
key_t key = ftok(".",100);
semid = semget(key,1,0666|IPC_CREAT);
if(semid == -1) perror("semget"),exit(-1);
semctl(semid,0,SETVAL,5);//允许5个进行并行访问
printf("信号量初始化成功\n");
signal(SIGINT,fa);//1
while(1);//2
}
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
int main(){
key_t key = ftok(".",100);
int semid = semget(key,0,0);//获取时只需要key
if(semid == -1) perror("semget"),exit(-1);
int i;
for(i=0;i<10;i++){//启动10个子进程
pid_t pid = fork();
if(pid == 0){//子进程的分支
struct sembuf op;
op.sem_num = 0;//下标
op.sem_op = -1;//减1,进程是新增
op.sem_flg = 0;//阻塞,如果非阻塞用IPC_NOWAIT
semop(semid,&op,1);//数组的地址=数组首元素地址
printf("访问共享资源\n");//如计数为0阻塞在19行
sleep(5); printf("共享资源访问完毕\n");
op.sem_op = 1;//加1,进程已完成访问
semop(semid,&op,1);//真正加1
exit(0);
}
}
}