這篇進程間通訊,包含的內容比較多,包括最基本的pipe和fifo,XSI(System V)標準和POSIX標準的消息隊列、信號量、共享內存,同時也有介紹mmap映射的相關內容,算是一個大總結,參考比較多的資料。算法
管道
管道是UNIX系統IPC的最古老形式,在shell下的表現形式爲管道線。每當在管道線中輸入一個由shell執行的命令序列時,shell爲每一條命令單首創建一進程,而後將前一條命令進程的標準輸出用管道與後一條命令的標準輸入相鏈接。管道有兩個主要侷限:
1).管道是半雙工的,即數據只能在一個方向上流動。
2).管道只能在具備公共祖先的進程之間使用。
管道是由調用pipe函數而建立的.shell
#include <unistd.h> int pipe(int filedes[2]); //成功返回0,錯誤返回-1。
經由參數filedes返回兩個文件描述符:filedes[0]爲讀而打開,filedes[1]爲寫而打開。filedes[1]的輸出是filedes[0]的輸入。單個進程中的管道幾乎沒有任何用處。一般,調用pipe的進程接着調用fork,這樣就建立了從父進程到子進程或反之的IPC通道。下面顯示了這種狀況數組
#include <unistd.h> #include <stdio.h> int main(){ int filedes[2]; char buf[80]; pid_t pid; pipe( filedes ); pid=fork(); if (pid > 0) { printf( "This is in the father process,here write a string to the pipe.\n" ); char s[] = "Hello world , this is write by pipe.\n"; write( filedes[1], s, sizeof(s) ); close( filedes[0] ); close( filedes[1] ); } else if(pid == 0) { printf( "This is in the child process,here read a string from the pipe.\n" ); read( filedes[0], buf, sizeof(buf) ); printf( "%s\n", buf ); close( filedes[0] ); close( filedes[1] ); } waitpid( pid, NULL, 0 ); return 0; }
#include <fcntl.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> #define FIFO_NAME "./my_fifo" #define BUFFER_SIZE 20 int main() { int pipe_fd; int res; int open_mode = O_RDONLY; char buffer[BUFFER_SIZE + 1]; memset(buffer, '\0', sizeof(buffer)); printf("Process %d opeining FIFO O_RDONLY\n", getpid()); pipe_fd = open(FIFO_NAME, open_mode); printf("Process %d result %d\n", getpid(), pipe_fd); if (pipe_fd != -1) { do{ res = read(pipe_fd, buffer, BUFFER_SIZE); printf("%s\n",buffer); }while(res > 0); close(pipe_fd); } else { exit(EXIT_FAILURE); } printf("Process %d finished \n", getpid()); exit(EXIT_SUCCESS); }
write緩存
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> #define FIFO_NAME "./my_fifo" #define BUFFER_SIZE 20 int main() { int pipe_fd; int res; int open_mode = O_WRONLY; char buffer[BUFFER_SIZE + 1]; if (access(FIFO_NAME, F_OK) == -1) { res = mkfifo(FIFO_NAME, 0777); if (res != 0) { fprintf(stderr, "Could not create fifo %s\n", FIFO_NAME); exit(EXIT_FAILURE); } } printf("Process %d opening FIFO O_WRONLY\n", getpid()); pipe_fd = open(FIFO_NAME, open_mode); printf("Process %d result %d\n", getpid(), pipe_fd); sleep(2); if (pipe_fd != -1) { while (1) { memset(buffer,0,sizeof(buffer)); scanf("%s",buffer); res = write(pipe_fd, buffer, sizeof(buffer)); if (res == -1) { fprintf(stderr, "Write error on pipe\n"); exit(EXIT_FAILURE); } } close(pipe_fd); } else { exit(EXIT_FAILURE); } printf("Process %d finish\n", getpid()); exit(EXIT_SUCCESS); }
XSI IPC服務器
#include <sys/ipc.h> key_t ftok(const char *path, int id); //成功返回關鍵字,失敗返回(key_t)-1。
path參數必須指向一個已有的文件。在產生關鍵字時只有id的低8位被使用。數據結構
struct ipc_perm { uid_t uid; /* owner's effective user id */ gid_t gid; /* owner's effective group id */ uid_t cuid; /* creator's effective user id */ gid_t cgid; /* creator's effective group id */ mode_t mode; /* access modes */ ... };
能夠調用msgctl、semctl或shmctl函數修改uid、gid和mode字段。爲了改變這些值,調用進程必須是IPC結構的建立者或超級用戶。對於任何IPC結構不存在執行權限。異步
消息隊列是消息的連接表,存放在內核中並由消息隊列標識符標識.。咱們將稱消息隊列爲「隊列」,其標識符爲「隊列ID」
1).每一個隊列都有一個msqid_ds結構與其相關。此結構規定了隊列的當前狀態。函數
struct msqid_ds { struct ipc_perm msg_perm; /* see Section 15.6.2 */ msgqnum_t msg_qnum; /* # of messages on queue */ msglen_t msg_qbytes; /* max # of bytes on queue */ pid_t msg_lspid; /* pid of last msgsnd() */ pid_t msg_lrpid; /* pid of last msgrcv() */ time_t msg_stime; /* last-msgsnd() time */ time_t msg_rtime; /* last-msgrcv() time */ time_t msg_ctime; /* last-change time */ ... };
#include <sys/msg.h> int msgget (key_t key, int flag); //成功返回消息隊列ID。錯誤返回-1。
#include <sys/msg.h> int msgctl (int msqid, int cmd, struct msqid_ds *buf); //成功返回0,錯誤返回-1。
cmd參數指定對於由msqid規定的隊列要執行的命令
IPC_STAT:把msgid_ds結構中的數據設置爲消息隊列的當前關聯值,即用消息隊列的當前關聯值覆蓋msgid_ds的值。
IPC_SET:若是進程有足夠的權限,就把消息列隊的當前關聯值設置爲msgid_ds結構中給出的值
IPC_RMID:刪除消息隊列post
#include <sys/msg.h> int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag); //成功返回0,錯誤返回-1。
#include <sys/msg.h> ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag); //成功返回消息的數據部分的尺寸,錯誤返回-1。
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <sys/msg.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #define BUFFSIZ 512 struct msg_st{ long int msg_type; char text[BUFFSIZ]; }; int main() { int running = 1; int msgid = -1; struct msg_st data; long int msgtype = 0; //注意1 //創建消息隊列 msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } //從隊列中獲取消息,直到遇到end消息爲止 while(running) { if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1) { fprintf(stderr, "msgrcv failed with errno: %d\n", errno); exit(EXIT_FAILURE); } printf("You wrote: %s\n",data.text); //遇到end結束 if(strncmp(data.text, "end", 3) == 0) running = 0; } //刪除消息隊列 if(msgctl(msgid, IPC_RMID, 0) == -1) { fprintf(stderr, "msgctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
發送測試
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/msg.h> #include <errno.h> #define MAX_TEXT 512 struct msg_st { long int msg_type; char text[MAX_TEXT]; }; int main() { int running = 1; struct msg_st data; char buffer[BUFSIZ]; int msgid = -1; //創建消息隊列 msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if(msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } //向消息隊列中寫消息,直到寫入end while(running) { //輸入數據 printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); data.msg_type = 1; //注意2 strcpy(data.text, buffer); //向隊列發送數據 if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } //輸入end結束輸入 if(strncmp(buffer, "end", 3) == 0) running = 0; sleep(1); } exit(EXIT_SUCCESS); }
XSI--信號量
struct semid_ds { struct ipc_perm sem_perm; /* see Section 15.6.2 */ unsigned short sem_nsems; /* # of semaphores in set */ time_t sem_otime; /* last-semop() time */ time_t sem_ctime; /* last-change time */ ... };
struct { unsigned short semval; /* semaphore value, always >= 0 */ pid_t sempid; /* pid for last operation */ unsigned short semncnt; /* # processes awaiting semval>curval */ unsigned short semzcnt; /* # processes awaiting semval==0 */ };
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/sem.h> union semun { int val; struct semid_ds *buf; unsigned short *arry; }; static int sem_id = 0; static int set_semvalue(); static void del_semvalue(); static int semaphore_p(); static int semaphore_v(); int main(int argc, char *argv[]) { char message = 'X'; int i = 0; //建立信號量 sem_id = semget((key_t)1234, 1, 0666 | IPC_CREAT); if(argc > 1) { //程序第一次被調用,初始化信號量 if(!set_semvalue()) { fprintf(stderr, "Failed to initialize semaphore\n"); exit(EXIT_FAILURE); } //設置要輸出到屏幕中的信息,即其參數的第一個字符 message = argv[1][0]; sleep(2); } for(i = 0; i < 10; ++i) { //進入臨界區 if(!semaphore_p()) exit(EXIT_FAILURE); //向屏幕中輸出數據 printf("%c", message); //清理緩衝區,而後休眠隨機時間 fflush(stdout); sleep(rand() % 3); //離開臨界區前再一次向屏幕輸出數據 printf("%c", message); fflush(stdout); //離開臨界區,休眠隨機時間後繼續循環 if(!semaphore_v()) exit(EXIT_FAILURE); sleep(rand() % 2); } sleep(10); printf("\n%d - finished\n", getpid()); if(argc > 1) { //若是程序是第一次被調用,則在退出前刪除信號量 sleep(3); del_semvalue(); } exit(EXIT_SUCCESS); } static int set_semvalue() { //用於初始化信號量,在使用信號量前必須這樣作 union semun sem_union; sem_union.val = 1; if(semctl(sem_id, 0, SETVAL, sem_union) == -1) return 0; return 1; } static void del_semvalue() { //刪除信號量 union semun sem_union; if(semctl(sem_id, 0, IPC_RMID, sem_union) == -1) fprintf(stderr, "Failed to delete semaphore\n"); } static int semaphore_p() { //對信號量作減1操做,即等待P(sv) struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1;//P() sem_b.sem_flg = SEM_UNDO; if(semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_p failed\n"); return 0; } return 1; } static int semaphore_v() { //這是一個釋放操做,它使信號量變爲可用,即發送信號V(sv) struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1;//V() sem_b.sem_flg = SEM_UNDO; if(semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_v failed\n"); return 0; } return 1; }
struct shmid_ds { struct ipc_perm shm_perm; /* see Section 15.6.2 */ size_t shm_segsz; /* size of segment in bytes */ pid_t shm_lpid; /* pid of last shmop() */ pid_t shm_cpid; /* pid of creator */ shmatt_t shm_nattch; /* number of current attaches */ time_t shm_atime; /* last-attach time */ time_t shm_dtime; /* last-detach time */ time_t shm_ctime; /* last-change time */ ... };
#include <unistd.h> #include <error.h> #include <sys/types.h> #include <sys/shm.h> #define SHM_SIZE 1024 #define SHM_MODE (SHM_R|SHM_W|IPC_CREAT) int main(){ void *shm=NULL; int *shared=NULL; int shmid=shmget((key_t)23,sizeof(int),SHM_MODE); if(shmid==-1){ perror("shmget error"); } shm=shmat(shmid,(void*)0,0); if(shm==(void*)-1){ perror("shmat error"); } shared=(int *)shm; int i=0; while(1){ sleep(1); *shared=i++; } if(shmdt(shm)==-1){ perror("shmdt error"); } return 0;
POSIX IPC
使用gcc編譯時,須要加上 -lrt
POSIX IPC名字標準:
#include <mqueue.h> mqd_t mq_open(const char *name, int oflag, /* mode_t mode, struct mq_attr *attr */); //成功返回消息隊列描述符,失敗返回-1 mqd_t mq_close(mqd_t mqdes); mqd_t mq_unlink(const char *name); //成功返回0,失敗返回-1
POSIX標準規定消息隊列屬性mq_attr必需要含有如下四個內容: long mq_flags //消息隊列的標誌:0或O_NONBLOCK,用來表示是否阻塞 long mq_maxmsg //消息隊列的最大消息數 long mq_msgsize //消息隊列中每一個消息的最大字節數 long mq_curmsgs //消息隊列中當前的消息數目 mq_attr結構的定義以下: #include <mqueue.h> mqd_t mq_getattr(mqd_t mqdes, struct mq_attr *attr); mqd_t mq_setattr(mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr); //成功返回0,失敗返回-1
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <fcntl.h> #include <mqueue.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> int main() { mqd_t mqid; mqid=mq_open("/myqueue",O_RDWR|O_CREAT,0666,NULL); if(mqid<0){ perror("open error"); exit(mqid); } struct mq_attr mqattr; if(mq_getattr(mqid,&mqattr)<0){ perror("get attr error"); exit(-1); } printf("mq_flags: %ld\n",mqattr.mq_flags); printf("mq_maxmsg: %ld\n",mqattr.mq_maxmsg); printf("mq_msgsize: %ld\n",mqattr.mq_msgsize); printf("mq_curmsgs: %ld\n",mqattr.mq_curmsgs); return 0; }
消息隊列使用
#include <mqueue.h> mqd_t mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio); //成功返回0,出錯返回-1 mqd_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio); //成功返回接收到消息的字節數,出錯返回-1 #ifdef __USE_XOPEN2K mqd_t mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abs_timeout); mqd_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abs_timeout); #endif
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <fcntl.h> #include <mqueue.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> int main() { mqd_t mqid; mqid=mq_open("/myqueue",O_RDWR|O_CREAT,0666,NULL); if(mqid<0){ perror("open error"); exit(mqid); } struct mq_attr mqattr; if(mq_getattr(mqid,&mqattr)<0){ perror("get attr error"); exit(-1); } int bufsize=mqattr.mq_msgsize; char *buf=(char *)malloc(sizeof(char)*bufsize); int prio=10; int running=1; while(running){ //輸入數據 printf("Enter some text: "); fgets(buf, bufsize, stdin); //向隊列發送數據 if(mq_send(mqid, buf, bufsize, prio) <0) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } //輸入end結束輸入 if(strncmp(buf, "end", 3) == 0) running = 0; sleep(1); prio++; } free(buf); mq_close(mqid); return 0; }
讀測試
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <fcntl.h> #include <mqueue.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> int main() { mqd_t mqid; mqid=mq_open("/myqueue",O_RDWR|O_CREAT,0666,NULL); if(mqid<0){ perror("open error"); exit(mqid); } struct mq_attr mqattr; if(mq_getattr(mqid,&mqattr)<0){ perror("get attr error"); exit(-1); } int bufsize=mqattr.mq_msgsize; char *buf=(char *)malloc(sizeof(char)*bufsize); int prio=10; int running=1; while(running){ if(mq_receive(mqid, buf, bufsize, NULL) <0) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } printf("rec: %s\n",buf); //輸入end結束輸入 if(strncmp(buf, "end", 3) == 0) running = 0; } free(buf); mq_close(mqid); return 0; }
POSIX--信號量
#include <semaphore.h> sem_t *sem_open(const char *name, int oflag); sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value); //成功返回信號量指針,失敗返回SEM_FAILED
#include <semaphore.h> int sem_close(sem_t *sem); int sem_unlink(const char *name); //成功返回0,失敗返回-1
信號量的P操做 #include <semaphore.h> int sem_wait (sem_t *sem); #ifdef __USE_XOPEN2K int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); #endif int sem_trywait (sem_t * sem); //成功返回0,失敗返回-1
信號量的V操做 #include <semaphore.h> int sem_post(sem_t *sem); //成功返回0,失敗返回-1
獲取當前信號量的值 #include <semaphore.h> int sem_getvalue(sem_t *sem, int *sval); //成功返回0,失敗返回-1
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <semaphore.h> #include <signal.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #define SEM1_NAME "/mysem1" #define SEM2_NAME "/mysem2" sem_t *pSem1; sem_t *pSem2; int stopflag=0; int val1,val2; static void sigAction(int signo){ if(signo==SIGINT) stopflag=1; } void threadfn1(){ while(stopflag!=1){ sem_wait(pSem2); sleep(1); printf("This is thread 1\n"); if(sem_getvalue(pSem1,&val1)<0) perror("get sem val err"); if(sem_getvalue(pSem2,&val2)<0) perror("get sem val err"); printf("val1= %d\tval2= %d\n",val1,val2); sem_post(pSem1); } } void threadfn2(){ while(stopflag!=1){ sem_wait(pSem1); sleep(1); printf("This is thread 2\n"); if(sem_getvalue(pSem1,&val1)<0) perror("get sem val err"); if(sem_getvalue(pSem2,&val2)<0) perror("get sem val err"); printf("val1= %d\tval2= %d\n",val1,val2); sem_post(pSem2); } } int main(){ if(signal(SIGINT,sigAction)==SIG_ERR) perror("catch SIGINT err"); pSem1=sem_open(SEM1_NAME,O_CREAT,0666,1); pSem2=sem_open(SEM2_NAME,O_CREAT,0666,1); pthread_t tid1,tid2; pthread_create(&tid1,NULL,&threadfn1,NULL); pthread_create(&tid2,NULL,&threadfn2,NULL); sleep(2); pthread_join(tid1,NULL); pthread_join(tid2,NULL); sem_close(pSem1); sem_unlink(SEM1_NAME); sem_close(pSem2); sem_unlink(SEM2_NAME); return 0; }
#include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); //若出錯則返回-1 int sem_destroy(sem_t *sem); //成功返回0,失敗返回-1
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <semaphore.h> #include <signal.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> sem_t pSem1; sem_t pSem2; int stopflag=0; int val1,val2; static void sigAction(int signo){ if(signo==SIGINT) stopflag=1; } void threadfn1(){ while(stopflag!=1){ sem_wait(&pSem2); sleep(1); printf("This is thread 1\n"); if(sem_getvalue(&pSem1,&val1)<0) perror("get sem val err"); if(sem_getvalue(&pSem2,&val2)<0) perror("get sem val err"); printf("val1= %d\tval2= %d\n",val1,val2); sem_post(&pSem1); } } void threadfn2(){ while(stopflag!=1){ sem_wait(&pSem1); sleep(1); printf("This is thread 2\n"); if(sem_getvalue(&pSem1,&val1)<0) perror("get sem val err"); if(sem_getvalue(&pSem2,&val2)<0) perror("get sem val err"); printf("val1= %d\tval2= %d\n",val1,val2); sem_post(&pSem2); } } int main(){ if(signal(SIGINT,sigAction)==SIG_ERR) perror("catch SIGINT err"); sem_init(&pSem1,1,1); sem_init(&pSem2,1,1); pthread_t tid1,tid2; pthread_create(&tid1,NULL,&threadfn1,NULL); pthread_create(&tid2,NULL,&threadfn2,NULL); sleep(2); pthread_join(tid1,NULL); pthread_join(tid2,NULL); sem_destroy(&pSem1); sem_destroy(&pSem2); return 0; }
POSIX--共享內存
#include <sys/mman.h> void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t offset); //成功返回映射到進程地址空間的起始地址,失敗返回MAP_FAILED
#include <sys/mman.h> int munmap(void *start, size_t len); //成功返回0,出錯返回-1
#include <sys/mman.h> int msync(void *start, size_t len, int flags); //成功返回0,出錯返回-1
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <fcntl.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> int main(){ int *memPtr; memPtr=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,0,0); if(memPtr==MAP_FAILED){ perror("mmap failed"); exit(-1); } *memPtr=0; if(fork()==0){ *memPtr=1; printf("child -- %d\n",*memPtr); exit(0); } sleep(1); printf("father -- %d\n",*memPtr); return 0; }
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <fcntl.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #define PATH_NAME "/tmp/memmap1" int main(){ int fd; fd=open(PATH_NAME,O_RDWR|O_CREAT,0666); if(fd<0){ perror("open failed"); exit(fd); } if(ftruncate(fd,sizeof(int))<0){ perror("change file size failed"); close(fd); exit(-1); } int *memPtr; memPtr=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); close(fd); if(memPtr==MAP_FAILED){ perror("mmap failed"); exit(-1); } *memPtr=10; printf("write:%d\n",*memPtr); return 0; }
#include <sys/mman.h> int shm_open(const char *name, int oflag, mode_t mode); //成功返回非負的描述符,失敗返回-1 int shm_unlink(const char *name); //成功返回0,失敗返回-1
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #define PATH_NAME "/shm" int main(){ int fd; fd=shm_open(PATH_NAME,O_RDWR|O_CREAT,0666); if(fd<0){ perror("open failed"); exit(fd); } if(ftruncate(fd,sizeof(int))<0){ perror("change file size failed"); close(fd); exit(-1); } int *memPtr; memPtr=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); close(fd); if(memPtr==MAP_FAILED){ perror("mmap failed"); exit(-1); } *memPtr=10; printf("write:%d\n",*memPtr); return 0; }
讀取
#include <unistd.h> #include <sys/types.h> #include <error.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> #define PATH_NAME "/shm" int main(){ int fd; fd=shm_open(PATH_NAME,O_RDWR|O_CREAT,0666); if(fd<0){ perror("open failed"); exit(fd); } if(ftruncate(fd,sizeof(int))<0){ perror("change file size failed"); close(fd); exit(-1); } int *memPtr; memPtr=(int*)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); close(fd); if(memPtr==MAP_FAILED){ perror("mmap failed"); exit(-1); } printf("read:%d\n",*memPtr); shm_unlink(PATH_NAME); return 0; }