sem的相关用法 一个简单的例子: 产生一个信号集,把信号集的id输出 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <stdio.h> int main() { key_t unique_key; int id; struct sembuf lock_it; //union semun options; int i; unique_key=ftok(".",'a'); id=semget(unique_key,1,IPC_CREAT | IPC_EXCL | 0666); printf("the sem id is %d/n",id); } 注: 1。创建IPC需要获取一个系统唯一的关键字:key,如: unique_key=ftok(".",'a'); 2。shmget是获得信号集的API函数,具体细节可以复习IPC相关知识。 共享内存的使用. 下面的例子是一个读者写着问题的解决方案 这是一个读者,写者问题 程序中读者和写着读取和写入的片段是一段共享内存 对共享内存的读写操作就像对程序的堆栈操作一样, shmat会返回一个字符指针的,提供读写的一篇区域 #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/sem.h> #include <stdlib.h> #define SHMKEY (key_t)0x10 #define SEMKEY (key_t)0x15 #define IFLAGS (IPC_CREAT | IPC_EXCL) #define ERR ((struct databuf*)-1) typedef char string[50]; struct databuf { int nbuf; //number of string buf string buf[10]; }; static semid,shmid; void fatal(char *mes) { perror(mes); exit(1); } void getseg(struct databuf **p) { if(shmid=shmget(SHMKEY,sizeof(struct databuf),0666|IFLAGS)==-1) fatal("shmget"); //link to data pointer if((*p=(struct databuf *)(shmat(shmid,0,0)))==ERR) fatal("shmat"); } int getsem() { //create semaphore if((semid=semget(SEMKEY,1,IFLAGS | 0666))==-1) fatal("semget"); if(semctl(semid,0,SETVAL,0)==-1) fatal("semctl"); return semid; } void myremove() { if(semctl(semid,0,IPC_RMID,NULL)==-1) fatal("semclt"); if(shmctl(shmid,IPC_RMID,NULL)==-1) fatal("shmctl"); } void reader(int semid,struct databuf *dbuf) { printf("This is reader process(son process)/n"); struct sembuf p={0,-1,0}; struct sembuf v={0,1,0}; char judge; while(1) { if(semop(semid,&p,1)==-1) fatal("semop"); if(dbuf->nbuf==0) { fprintf(stderr,"There is no data in the shared memory!/n"); semop(semid,&v,1); continue; } else { printf("%s",dbuf->buf[--dbuf->nbuf]); } if(semop(semid,&v,1)==-1) fatal("semop"); /* printf("Continue to read?(y/n)/n"); scanf("%c",&judge); if(judge=='Y' | judge=='y') continue; else berak;*/ } } void writer(int semid,struct databuf *dbuf) { printf("This is writer process(father process)/n"); struct sembuf p={0,-1,0}; struct sembuf v={0,1,0}; char judge; while(1) { //wait if(semop(semid,&p,1)==-1) fatal("semop"); //whether the buf full? if(dbuf->nbuf==10) { fprintf(stderr,"The buf is full!/n"); semop(semid,&v,1); continue; } else { printf("Please put data to the buf:/n"); scanf("%s",dbuf->buf[dbuf->nbuf++]); } if(semop(semid,&v,1)==-1) { fatal("semop"); } /* //continue to write printf("Continue to write?(y/n)/n"); scanf("%c",&judge); if(judge=='Y' | judge=='y') continue; else exit(0); */ } } int main() { int pid; struct databuf *buf; //myremove(); //initial semaphore set semid=getsem(); //create and link to shared memory getseg(&buf); //take care switch(pid=fork()) { case -1: fatal("fork()"); case 0: writer(semid,buf); myremove(); break; default: reader(semid,buf); break; } // remove(); exit(0); } 管道机制 无名管道 父子进程之间通过无名管道通信 pipe函数创建一个无名管道,参数为一个大小为2的int数组 管道有两个端口,一个为读端口,一个为些端口 其中fd[0]为读端口,fd[1]为写端口 下面的程序子进程向父进程说了一生:“hello world!” #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> int main() { int fd[2],nbytes; pid_t child_pid; char string[]="hello,world!/n"; char read_buff[80]; pipe(fd); if((child_pid=fork())==-1) { perror("fork"); exit(1); } //child process write to pipe //father process read the pipe if(child_pid==0) { close(fd[0]); write(fd[1],string,strlen(string)); _exit(0); } else { close(fd[1]); nbytes=read(fd[0],read_buff,80); printf("Recieve string:%s/n",read_buff); } return 0; } 命名管道 管道还有另外一种类型,那就是命名管道,命名管道创建之后, 我们可以相使用任何其他文件一样,对命名管道进行读写操作 下面的例子,程序一创建了一个命名管道,在从其中读取数据 程序二向这个命名管道中写入数据,从而达到两个进程之间的 通信的目的 程序一: #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <linux/stat.h> #define FIFO_FILE "sampleFIFO" int main() { FILE *fp; char readbuf[80]; //create the FIFO if id does not exist umask(0); //create the FIFO in the file system mknod(FIFO_FILE,S_IFIFO|0666,0); while(1) { //open the FIFO fp=fopen(FIFO_FILE,"r"); fgets(readbuf,80,fp); printf("Receive string:%s/n",readbuf); //close the FIFO fclose(fp); } return 0; } 程序二: #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <linux/stat.h> #define FIFO_FILE "sampleFIFO" int main() { FILE *fp; char readbuf[80]; //create the FIFO if id does not exist umask(0); //create the FIFO in the file system mknod(FIFO_FILE,S_IFIFO|0666,0); while(1) { //open the FIFO fp=fopen(FIFO_FILE,"r"); fgets(readbuf,80,fp); printf("Receive string:%s/n",readbuf); //close the FIFO fclose(fp); } return 0; }