共享內存函數封裝:linux
1 #include <unistd.h> 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 #include <sys/mman.h> 6 #include <sys/ipc.h> 7 #include <sys/shm.h> 8 #include <sys/sem.h> 9 10 #include <stdlib.h> 11 #include <stdio.h> 12 #include <errno.h> 13 #include <string.h> 14 15 #include <sys/ipc.h> 16 #include <sys/sem.h> 17 #include "myipc_sem.h" 18 19 20 union semun { 21 int val; /* Value for SETVAL */ 22 struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ 23 unsigned short *array; /* Array for GETALL, SETALL */ 24 struct seminfo *__buf; /* Buffer for IPC_INFO 25 (Linux specific) */ 26 }; 27 28 //@返回值 0 正確 其餘錯誤 29 int sem_creat(int key, int *semid) 30 { 31 int ret = 0; 32 //int tmpsemid = 0; 33 34 if (semid == NULL) 35 { 36 ret = SEMERR_PARAM; 37 printf("func sem_creat() err:%d\n", ret); 38 return ret; 39 } 40 ret = semget(key, 1, 0666| IPC_CREAT | IPC_EXCL); 41 if (ret == -1) 42 { 43 ret = errno; 44 //perror("semget"); 45 if (errno == EEXIST) 46 { 47 ret = SEMERR_EEXIST; 48 printf("func sem_creat() 檢測到信號量集已經存在:%d\n", ret); 49 return ret; 50 } 51 } 52 *semid = ret; 53 54 ret = sem_setval(*semid, 1); 55 if (ret != 0) 56 { 57 printf("func sem_setval() err:%d\n", ret); 58 return ret; 59 } 60 ret = 0; 61 return ret; 62 } 63 64 int sem_open(int key, int *semid) 65 { 66 int ret = 0; 67 68 if (semid == NULL) 69 { 70 ret = SEMERR_PARAM; 71 printf("func sem_open() err:%d\n", ret); 72 return ret; 73 } 74 75 ret = semget(key, 0, 0); 76 if (ret == -1) 77 { 78 ret = errno; 79 printf("func sem_open() 失敗:%d\n", ret); 80 return ret; 81 } 82 *semid = ret; 83 ret = 0; 84 return ret; 85 } 86 87 int sem_setval(int semid, int val) 88 { 89 int ret = 0; 90 union semun su; 91 su.val = val; 92 ret = semctl(semid, 0, SETVAL, su); 93 return ret; 94 } 95 96 /* 97 int sem_getval(int semid, int *val) 98 { 99 int ret = 0; 100 int tmpval; 101 if (val == NULL) 102 { 103 ret = SEMERR_PARAM; 104 printf("func sem_getval() err:%d\n", ret); 105 return ret; 106 } 107 union semun su; 108 tmpval = su.val ; 109 ret = semctl(semid, 0, GETVAL, su); 110 *val = tmpval ; 111 printf("val:%d\n", tmpval); 112 return ret; 113 } 114 */ 115 int sem_getval(int semid, int *myval) 116 { 117 int ret = 0; 118 int val; 119 union semun su; 120 val = su.val ; 121 //信號量 計數值 122 ret = semctl(semid, 0, GETVAL, su); 123 //printf("val:%d\n", val); 124 125 *myval = ret; 126 ret = 0; 127 return ret; 128 } 129 130 //信號量p操做時候,須要傳遞好幾個信息給linux內核 131 //因此linux內核定義了一個結構 132 //我要操做信號量集的下標 0 133 //我要執行什麼操做 -1 +1 134 //我按照什麼策略執行操做 0 UNDO NOWAITing 135 int sem_p(int semid) 136 { 137 struct sembuf buf = {0, -1, 0}; 138 int ret = 0; 139 ret = semop(semid, &buf, 1); 140 return ret; 141 } 142 143 int sem_v(int semid) 144 { 145 struct sembuf buf = {0, 1, 0}; 146 int ret = 0; 147 ret = semop(semid, &buf, 1); 148 return ret; 149 }
信號量函數封裝:函數
1 #define _OS_LINUX_ 2 3 #if defined _OS_LINUX_ 4 #include <stdio.h> 5 #include <errno.h> 6 #include <unistd.h> 7 #include <memory.h> 8 #include <sys/ipc.h> 9 #include <sys/shm.h> 10 #include <sys/sem.h> 11 #include <sys/msg.h> 12 #include "myipc_shm.h" 13 14 #endif 15 16 int shmflag = 0; 17 int shmkey; 18 19 /*********************************************************************** 20 功能描述: 建立共享內存 21 參數說明: shmname [in] 是共享內存名,系統中惟一標誌 22 shmsize [in] 是要建立的共享內存的大小; 23 shmhdl [out] 共享內存的句柄. 24 返回值: 返回0函數執行成功;非0返回錯誤碼 25 ************************************************************************/ 26 int IPC_CreatShm(char *shmseedfile, int shmsize, int *shmhdl) 27 { 28 if(shmflag == 0) //判斷接口中共享內存key是否已經存在 29 { 30 shmkey = ftok(shmseedfile, 'c'); 31 if (shmkey == -1) 32 { 33 perror("ftok"); 34 return -1; 35 } 36 37 shmflag = 1; 38 } 39 40 //建立共享內存 41 *shmhdl = shmget(shmkey,shmsize,IPC_CREAT|0666); 42 if (*shmhdl == -1) //建立失敗 43 return -2; 44 return 0; 45 46 } 47 /*********************************************************************** 48 功能描述: 關聯共享內存 49 參數說明: shmhdl [in] 共享的句柄 50 mapaddr [out] 共享內存首地址 51 返回值: 返回0函數執行成功;非0返回錯誤碼 52 ************************************************************************/ 53 int 54 IPC_MapShm(int shmhdl, void **mapaddr) 55 { 56 void *tempptr = NULL; 57 58 //鏈接共享內存 59 tempptr = (void *)shmat(shmhdl,0,SHM_RND); 60 if ((int)tempptr == -1) //共享內存鏈接失敗 61 return -1; 62 *mapaddr = tempptr; //導出共享內存首指針 63 64 return 0; 65 } 66 /*********************************************************************** 67 功能描述: 取消共享內存關聯 68 參數說明: unmapaddr [in] 共享內存首地址 69 返回值: 返回0函數執行成功;非0返回錯誤碼 70 ************************************************************************/ 71 int IPC_UnMapShm(void *unmapaddr) 72 { 73 int rv; 74 //取消鏈接共享內存 75 rv = shmdt((char *)unmapaddr); 76 if (rv == -1) //取消鏈接失敗 77 return -1; 78 79 return 0; 80 } 81 /*********************************************************************** 82 功能描述: 刪除共享內存 83 參數說明: shmhdl [in] 共享的句柄 84 返回值: 返回0函數執行成功;非0返回錯誤碼 85 ************************************************************************/ 86 int IPC_DelShm(int shmhdl) 87 { 88 int rv; 89 //刪除共享內存 90 rv = shmctl(shmhdl,IPC_RMID,NULL); 91 if(rv < 0) //刪除共享內存失敗 92 return -1; 93 return 0; 94 }
多進程操做共享內存:oop
1 #include <sys/types.h> 2 #include <unistd.h> 3 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include <string.h> 7 8 #include <signal.h> 9 #include <errno.h> 10 #include <signal.h> 11 #include <sys/wait.h> 12 13 #include "myipc_sem.h" 14 #include "myipc_shm.h" 15 16 int g_key = 0x3333; 17 18 void TestFunc(int loopnum) 19 { 20 printf("loopnum:%d\n", loopnum); 21 22 int ncount = 0; 23 int ret = 0; 24 int shmhdl = 0; 25 int *addr = NULL; 26 27 int semid = 0; 28 sem_open(g_key, &semid); 29 30 31 sem_p(semid); //臨界區開始 32 // 33 ret = IPC_CreatShm(".", 0, &shmhdl); 34 35 ret =IPC_MapShm(shmhdl, (void **)&addr); 36 *((int *)addr) = *((int *)addr) + 1; 37 ncount = *((int *)addr); 38 printf("ncount:%d\n", ncount); 39 //addr[0] = addr[0] +1; 40 ret =IPC_UnMapShm(addr); 41 sleep(2); 42 43 sem_v(semid); //臨界區開始 44 // 45 printf("進程正常退出:%d\n", getpid()); 46 } 47 48 int main(void ) 49 { 50 int res; 51 int procnum=10; 52 int loopnum = 100; 53 54 55 int i=0,j = 0; 56 57 printf("請輸入要建立子進程的個數 : \n"); 58 scanf("%d", &procnum); 59 60 printf("請輸入讓每一個子進程測試多少次 :\n"); 61 scanf("%d", &loopnum); 62 63 //共享內存建立 64 int ret = 0; 65 int shmhdl = 0; 66 ret = IPC_CreatShm(".", sizeof(int), &shmhdl); 67 if (ret != 0) 68 { 69 printf("func IPC_CreatShm() err:%d \n", ret); 70 return ret; 71 } 72 73 74 //信號量的建立 75 int semid = 0; 76 ret = sem_creat(g_key, &semid); 77 if (ret != 0) 78 { 79 printf("func sem_creat() err:%d,從新按照open打開信號量 \n", ret); 80 if (ret == SEMERR_EEXIST) 81 { 82 ret = sem_open(g_key, &semid); 83 if (ret != 0) 84 { 85 printf("按照打開的方式,從新獲取sem失敗:%d \n", ret); 86 return ret; 87 } 88 } 89 else 90 { 91 return ret; 92 } 93 94 } 95 96 int val = 0; 97 ret = sem_getval(semid, &val); 98 if (ret != 0 ) 99 { 100 printf("func sem_getval() err:%d \n", ret); 101 return ret; 102 } 103 printf("sem val:%d\n", val); 104 getchar(); 105 106 pid_t pid; 107 108 for (i=0; i<procnum; i++) 109 { 110 pid = fork(); //有幾個fork就有幾個子進程 111 if (pid == 0) 112 { 113 for (j=0; j<loopnum; j ++) 114 { 115 TestFunc(j); 116 } 117 exit(0); 118 } 119 120 } 121 122 //讓全部的子進程退出 父進程才退出 123 124 /* 125 while(1) 126 { 127 res = wait(NULL);// 128 if(res==-1) 129 { 130 if(errno==EINTR) //若阻塞中有別的信號中斷 131 { 132 continue; 133 } 134 break; 135 } 136 } 137 */ 138 139 int mypid = 0; 140 while ( (mypid= waitpid(-1, NULL, WNOHANG)) > 0) 141 { 142 //printf("退出的子進程pid爲:mypid:%d \n", mypid); 143 ; 144 } 145 146 147 printf("父進程退出 hello...\n"); 148 return 0; 149 }