赞
踩
目录
高级信号发送函数sigqueue(),比kill()在发射信号时能携带更多信息
高级信号接收函数sigaction(),比signal()在接收信号时能获取更多信息
- #include <stdio.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/wait.h>
-
- int main()
- {
- pid_t pid;
- int fd[2];
- char readBuf[128];
-
- if(pipe(fd) < 0){
- perror("pipe");
- exit(-1);
- }
-
- pid = vfork();
-
- if(pid == 0){
- printf("this is child process\n");
- close(fd[0]);
- write(fd[1],"my name is child process,haozige handsome",128);
- printf("child process is done\n");
- exit(0);
-
- }else if(pid > 0){
- printf("this is father process\n");
- wait(NULL);
- close(fd[1]);
- read(fd[0],readBuf,128);
- printf("from child process content is %s\n",readBuf);
- printf("father process is done\n");
-
- }else{
- printf("fork is fail\n");
- perror("fork");
- exit(-1);
- }
-
- return 0;
- }
与无名管道不同的是,命名管道可以在没有关系的两个进程间进行通信
由于read()函数在读不到数据时会阻塞,因此我们在读数据的进程创建命名管道,并阻塞等待写数据的进程向命名管道写入数据 ,在创建命名管道时,给管道的权限建议是0600,即可读可写可执行
读数据进程
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
-
- int main(int argc,char *argv[])
- {
- if(argc < 2){
- printf("missing paramiter -> FIFO");
- exit(-1);
- }
-
- char readBuf[128];
- int readSize = 0;
-
- if(mkfifo(argv[1],0600) < 0){
- perror("mkfifo");
- exit(-1);
- }
-
- int fd = open(argv[1],O_RDONLY);
- if(fd < 0){
- perror("open");
- exit(-1);
- }
-
- while(1){
- memset(readBuf,'\0',128);
- readSize = read(fd,readBuf,128);
- printf("read data from FIFO %s, content is %s\n",argv[1],readBuf);
- }
- close(fd);
-
- return 0;
- }
命名管道是类似创建文件的形式创建的
写数据进程
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
-
- int main(int argc,char *argv[])
- {
- if(argc < 2){
- printf("missing paramiter -> FIFO");
- exit(-1);
- }
-
- char Msg[128] = "from write FIFO send jiangxiaoya is pigHead";
-
- int fd = open(argv[1],O_WRONLY);
-
- while(1){
- write(fd,Msg,strlen(Msg));
- sleep(1);
- }
- close(fd);
-
- return 0;
- }
当写数据进程启动后,读数据进程不再阻塞,开始读取命名管道的数据
命名管道的应用:
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
-
- int main(int argc,char *argv[])
- {
- if(argc < 2){
- printf("missing parameter -> keyfile\n");
- exit(-1);
- }
- key_t key;
- key = ftok(argv[1],'z');
-
- if(key == -1){
- perror("ftok");
- exit(-1);
- }else{
- printf("key value is %d\n",key);
- }
-
- key = ftok(argv[1],159);
-
- if(key == -1){
- perror("ftok");
- exit(-1);
- }else{
- printf("key value is %d\n",key);
- }
-
- return 0;
- }
消息队列是一个存储信息的链表,全双工通信,进程终止后,数据不会丢式
向消息队列添加各种消息的sendMsg进程
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <string.h>
-
- struct Msgbuf
- {
- long mtype;
- char mtext[128];
- };
-
- int main(int argc,char *argv[])
- {
- key_t key;
- key = ftok("./keyfile.txt",'z');
-
- if(key == -1){
- perror("ftok");
- exit(-1);
- }
-
- int msgID = msgget(key,IPC_CREAT|0777);
-
- if(msgID == -1){
- perror("msgget");
- exit(-1);
- }
-
- struct Msgbuf sendMsg = {
- 130,
- "this is sendMsg process"
- };
-
- struct Msgbuf sendMsg1 = {
- 181,
- "haozige handsome"
- };
-
- struct Msgbuf sendMsg2 = {
- 166,
- "jiangxiaoya pigHand"
- };
-
- msgsnd(msgID,&sendMsg,strlen(sendMsg.mtext),0);
- msgsnd(msgID,&sendMsg1,strlen(sendMsg1.mtext),0);
- msgsnd(msgID,&sendMsg2,strlen(sendMsg2.mtext),0);
-
- struct Msgbuf receive;
- memset(&receive,0,sizeof(receive));
- msgrcv(msgID,&receive,sizeof(receive.mtext),2349,0);
-
- printf("this is sendMsg process,receive msg from messageQueue,content is %s\n",receive.mtext);
-
- //msgctl(msgID,IPC_RMID,NULL);
-
- return 0;
- }
根据消息字段读取消息队列中的消息的receive进程,要使用同一个键值才能访问到同一个消息队列
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <string.h>
- #include <unistd.h>
-
- struct Msgbuf
- {
- long mtype;
- char mtext[128];
- };
-
- int main(int argc,char *argv[])
- {
- key_t key;
- key = ftok("./keyfile.txt",'z');
-
- if(key == -1){
- perror("ftok");
- exit(-1);
- }
-
- int msgID = msgget(key,IPC_CREAT|0777);
-
- if(msgID == -1){
- perror("msgget");
- exit(-1);
- }
-
- struct Msgbuf sendMsg = {
- 2349,
- "this is receiveMsg process"
- };
-
- msgsnd(msgID,&sendMsg,strlen(sendMsg.mtext),0);
-
- struct Msgbuf receive;
- struct Msgbuf receive1;
- struct Msgbuf receive2;
- memset(&receive,0,sizeof(receive));
- memset(&receive1,0,sizeof(receive1));
- memset(&receive2,0,sizeof(receive2));
-
- msgrcv(msgID,&receive,sizeof(receive.mtext),130,0);
- msgrcv(msgID,&receive1,sizeof(receive1.mtext),181,0);
- msgrcv(msgID,&receive2,sizeof(receive2.mtext),166,0);
-
- printf("this is receiveMsg process,receive msg from messageQueue,content is %s\n",receive.mtext);
- sleep(5);
- printf("this is receiveMsg process,receive msg from messageQueue,content is %s\n",receive1.mtext);
- sleep(5);
- printf("this is receiveMsg process,receive msg from messageQueue,content is %s\n",receive2.mtext);
-
- msgctl(msgID,IPC_RMID,NULL);
-
- return 0;
- }
创建一块共享内存,writeShm进程每隔1秒向共享内存写入一个字母,readShm进程每隔一秒从共享内存读取一个字母,当从共享内存连续10s读不到数据后,会删除该共享内存
my_writeShm进程:
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/shm.h>
-
-
- int main(int argc,char *argv[])
- {
- key_t key = ftok(".",'z');
-
- if(key == -1){
- perror("ftok");
- exit(-1);
- }
-
- int shmID = shmget(key,1024*4,IPC_CREAT|0666);
-
- if(shmID == -1){
- perror("shmget");
- exit(-1);
- }
-
- char *tmp = (char *)shmat(shmID,NULL,0);
- memset(tmp,'\0',1024*4);
- char *str = "abcdefghijklmnopqrstuvwxyz";
-
- while(*str != '\0'){
- sprintf(tmp,"%c",*str);
- sleep(1);
- *str++;
- }
- memset(tmp,'\0',1024*4);
-
- shmdt(tmp);
-
- //shmctl(shmID,IPC_RMID,NULL);
-
- return 0;
- }
my_readShm进程:
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/shm.h>
-
-
- int main(int argc,char *argv[])
- {
- key_t key = ftok(".",'z');
-
- if(key == -1){
- perror("ftok");
- exit(-1);
- }
-
- int shmID = shmget(key,1024*4,IPC_CREAT|0666);
-
- if(shmID == -1){
- perror("shmget");
- exit(-1);
- }
-
- char *tmp = (char *)shmat(shmID,NULL,0);
- while(1){
- printf("shm content is %s\n",tmp);
- sleep(1);
-
- if(strlen(tmp) == 0){
- sleep(10);
- if(strlen(tmp) == 0){
- break;
- }
- }
- }
- shmdt(tmp);
-
- shmctl(shmID,IPC_RMID,NULL);
-
- return 0;
- }
将三者进程间的通信看作纸条上的通信
使用signal()函数实现Linux定时器,每隔2s输出一个字符串,使用kill()关闭这个定时器
signal()进程
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/time.h>
- #include <signal.h>
-
- static int i = 0;
-
- void time_handle(int signum)
- {
- i++;
- if(i == 2000){
- printf("2s to hello haozige,my process pid is %d\n",getpid());
- i = 0;
- }
- }
-
- int main()
- {
-
- struct itimerval tmp;
-
- tmp.it_value.tv_sec = 0;
- tmp.it_value.tv_usec = 500*1000;
-
- tmp.it_interval.tv_sec = 0;
- tmp.it_interval.tv_usec = 500;
-
- if(setitimer(ITIMER_REAL,&tmp,NULL) == -1){
- perror("setitimer");
- exit(-1);
- }//SIGALRM
-
- signal(SIGALRM,time_handle);
- while(1);
- return 0;
- }
相关结构体
kill()进程
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <signal.h>
-
-
- int main(int argc,char *argv[])
- {
- if(argc < 2){
- printf("missing parameter -> process pid\n");
- exit(-1);
- }
-
- pid_t pid = atoi(argv[1]);
-
- kill(pid,SIGINT);
- sleep(1);
- printf("pid is %d process is done!\n",pid);
- return 0;
- }
sigset_t sa_mask:
int sa_flags:
siginfo_t 结构:保存的其他信息
进程A使用sigqueue向进程B发送信号和携带信息:年龄21和年龄20两个整型数,进程B收到该信号后进行处理
进程A:sigqueue()
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <signal.h>
-
- int main(int argc,char *argv[])
- {
- if(argc < 2){
- printf("missing parameter -> process pid\n");
- exit(-1);
- }
-
- pid_t pid = atoi(argv[1]);
-
- int tmp = 0;
- union sigval msg;
- msg.sival_int = 21;
-
- while(1){
- sigqueue(pid,SIGUSR1,msg);
- tmp++;
- if(tmp == 5){
- msg.sival_int = 19;
- }
- if(tmp == 10){
- kill(pid,SIGINT);
- break;
- }
- sleep(1);
- }
- return 0;
- }
进程B:sigaction()
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/time.h>
- #include <signal.h>
-
- static int i = 0;
-
- void time_handle(int signum,siginfo_t *tmp,void *context)
- {
-
- if(context != NULL){
- printf("msg from pid %d process\n",tmp->si_pid);
- printf("age is %d\n",tmp->si_value.sival_int);
- printf("age is %d\n",tmp->si_int);
- }else{
- printf("Segment errors may occur\n");
- printf("1%s",(char *)context);
- }
- }
-
- int main()
- {
- struct sigaction sigMsg;
- printf("my process pid is %d\n",getpid());
-
- sigMsg.sa_flags = SA_SIGINFO;
- sigMsg.sa_sigaction = time_handle;
-
- sigemptyset(&sigMsg.sa_mask);//初始化信号集,清空该信号集里的所有信号
-
- sigaction(SIGUSR1,&sigMsg,NULL);
-
- while(1);
- return 0;
- }
信号量并非单个非负值,必须定义为多个信号量的集合,称为信号量集
信号量保证子进程先运行,父进程后运行,同理子进程先获得临界资源,父进程后获得临界资源
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <unistd.h>
-
- //semctl()参数4,保存信号量的信息或者设置信号量的信息
- union semun {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- struct seminfo *__buf;
- };
-
- //p操作
- void handle_P(int id)
- {
- struct sembuf pBuf;
- pBuf.sem_num = 0;
- pBuf.sem_op = -1;
- pBuf.sem_flg = SEM_UNDO;
- if(semop(id,&pBuf,1) < 0){
- perror("semop");
- exit(-1);
- }
- }
-
- //v操作
- void handle_V(int id)
- {
- struct sembuf vBuf;
- vBuf.sem_num = 0;
- vBuf.sem_op = 1;
- vBuf.sem_flg = SEM_UNDO;
- if(semop(id,&vBuf,1) < 0){
- perror("semop");
- exit(-1);
- }
- }
-
- int main(int argc,char *argv[])
- {
- key_t key = ftok(".",'z');
-
- if(key == -1){
- perror("ftok");
- exit(-1);
- }
-
- int semID = semget(key,1,IPC_CREAT|0666);
-
- if(semID < 0){
- perror("semget");
- exit(-1);
- }
-
- union semun tmp;
- tmp.val = 0; //信号量初始值
-
- if(semctl(semID,0,SETVAL,tmp) < 0){
- perror("semctl");
- exit(-1);
- }
- pid_t pid = fork();
- if(pid > 0){
- //如果父进程先运行,由于信号量初始值为0,执行p操作后父进程进入阻塞状态
- printf("father process is wait\n");
- handle_P(semID);//p操作
- printf("child process lets father process cancel wait\n");
-
- semctl(semID,0,IPC_RMID);
-
- }else if(pid == 0){
- //子进程运行
- printf("child process function\n");
- //5s后执行v操作唤醒父进程
- printf("wake up the father process after 5s\n");
- int i;
- for(i=1;i<6;i++){
- sleep(1);
- printf("%d\n",i);
- }
- handle_V(semID);//v操作
-
- }else{
- perror("fork");
- exit(-1);
- }
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。