<strike id="5ntnv"><i id="5ntnv"><del id="5ntnv"></del></i></strike>
<strike id="5ntnv"></strike><ruby id="5ntnv"></ruby><del id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></del><strike id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></strike>
<strike id="5ntnv"></strike>
<strike id="5ntnv"></strike>
<span id="5ntnv"><dl id="5ntnv"></dl></span>
<strike id="5ntnv"><i id="5ntnv"><del id="5ntnv"></del></i></strike><th id="5ntnv"><noframes id="5ntnv"><span id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></span>
<span id="5ntnv"></span>
<strike id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></strike>
<strike id="5ntnv"><dl id="5ntnv"><del id="5ntnv"></del></dl></strike><strike id="5ntnv"><i id="5ntnv"></i></strike><span id="5ntnv"></span>
<strike id="5ntnv"></strike>
<strike id="5ntnv"></strike>
<th id="5ntnv"><noframes id="5ntnv">
<ruby id="5ntnv"></ruby>
<strike id="5ntnv"><dl id="5ntnv"></dl></strike>

貴州網站建設公司貴州網站建設公司

IPC通信:Posix信號燈

  信號燈用來實現同步——用于多線程,信P信號多進程之間同步共享資源(臨界資源)。信P信號信號燈分兩種,信P信號一種是信P信號有名信號燈,一種是信P信號基于內存的信號燈。有名信號燈,信P信號是信P信號根據外部名字標識,通常指代文件系統中的信P信號某個文件。而基于內存的信P信號信號燈,它主要是信P信號把信號燈放入內存的,基于內存的信P信號信號燈,同步多線程時,信P信號可以放到該多線程所屬進程空間里;如果是信P信號同步多進程,那就需要把信號燈放入到共享內存中(方便多個進程訪問)。信P信號

  有名信號燈和基于內存的信P信號信號燈,具體區別體現在創建和銷毀兩個函數。有名信號燈使用sem_open和sem_close函數。基于內存的信號燈使用sem_init和sem_destroy函數。sem_init的參數可以控制是同步多線程,還是多進程;且該函數只能調用1次,因為調用后信號燈就存在了( 內存指針存在)。一般,使用基于內存的信號燈同步同進程多線程,使用有名信號燈同步多進程。

有名信號燈同步多線程:

1 1.sem_open函數。 2 功能:創建并初始化信號燈,如果存在就返回存在的信號燈。 3 頭文件:#include <semaphore.h> 4 函數原型:sem_t * sem_open(const char * name,int oflag,mode_t mode,unsigned int value); 5    或者:sem_t * sem_open(const char * name,int oflag); 6 參數:name是給信號燈指定一個名字。oflag的值為O_CREAT,表示如果信號燈不存在,創建信號燈;為O_CREAT|O_EXCL,如果信號燈不存在報錯。后面兩個參數,只有新建信號燈時使用。mode為信號燈的權限(0644),value為信號燈的值。 7 返回值:成功時,返回信號燈的指針,錯誤返回SEM_FAILED 8  9 2.sem_close函數。10 功能:關閉引用信號燈,信號燈引用計數減1。11 頭文件:#include <semaphore.h>12 函數原型:int sem_close(sem_t * sem)13 參數:sem為信號燈的指針14 返回值:成功時,返回0,失敗,-115 注:每個信號燈有一個引用計數器記錄當前打開次數.關閉一個信號燈并沒有將它從系統中刪除,而是信號燈引用計數減116 17 18 3.sem_unlink函數19 功能:信號燈引用計數為0時,從系統中刪除信號燈。20 頭文件:#include <semaphore.h>21 函數原型:int sem_close(const char *name)22 參數:name為信號燈的外部名字23 返回值:成功時,返回0,失敗,-124 25 4.sem_wait/sem_trywait函數26 功能:等待共享資源,信號燈值為0就睡眠,信號燈值大于0,就使用共享資源,信號燈值減1。sem_trywait當信號燈值為0時,不睡眠,報錯。27 頭文件:#include <semaphore.h>28 函數原型:int sem_wait(sem_t *sem),int sem_trywait(sem_t *sem)29 參數:sem為信號燈指針30 返回值:成功時,返回0,失敗,-131 32 5.sem_getvalue函數33 功能:獲得信號燈的值34 頭文件:#include <semaphore.h>35 函數原型:int sem_getvalue(sem_t *sem,int *valp)36 參數:sem為信號燈指針,valp為信號燈的值37 返回值:成功時,返回0,失敗,-138 39 6.sem_post函數40 功能:使用完共享資源后,信號燈值加1,喚醒其他睡眠的。41 頭文件:#include <semaphore.h>42 函數原型:int sem_post(sem_t *sem)43 參數:sem為信號燈指針44 返回值:成功時,返回0,失敗,-1

示例代碼:

1 /*semopen_pth.c*/ 2 #include <stdio.h> 3 #include <semaphore.h> 4 #include <fcntl.h> 5 #include <pthread.h> 6                                                                                 7 void print(); 8 void * thread_function(void *arg); 9 sem_t * sem;10                                                                                11 int main(int argc,char * argv[])12 { 13         int n=0;14         pthread_t tid;15         if(argc != 2)16         { 17                 printf("Usage:%s name.\n",argv[0]);18                 exit(0);19         }20         //init semaphore21         sem=sem_open(argv[1],O_CREAT,0644,3);22         while(n++<5)23         { 24                 if((pthread_create(&tid,NULL,thread_function,NULL))!=0)25                 { 26                         printf("can't create pthread.\n");27                         exit(0);28                 }29         }30         pthread_join(tid,NULL); //主線程需要等會其它線程31         sem_close(sem);32         sem_unlink(argv[1]);33         return 0;34 }35                                                                                36 void * thread_function(void *arg)37 { 38         sem_wait(sem);39         print();40         sleep(1); //因為共享段執行過快,不能達到同步效果,所以需要睡眠41         sem_post(sem);42         printf("finish, pthread_id is %d\n",pthread_self());43 }44                                                                                45 void print()46 {  47         int value;48         printf("pthread_id is %d, get the resource\n",pthread_self());49         sem_getvalue(sem,&value);50         printf("now,the semaphore value is %d\n",value);51 }

編譯并執行:

1 root@linux:/mnt/hgfs/C_libary# gcc -lpthread -o semopen_pth semopen_pth.c 2 semopen_pth.c: In function ‘main’: 3 semopen_pth.c:17: warning: incompatible implicit declaration of built-in function ‘exit’ 4 semopen_pth.c:26: warning: incompatible implicit declaration of built-in function ‘exit’ 5 semopen_pth.c: In function ‘thread_function’: 6 semopen_pth.c:41: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’ 7 semopen_pth.c: In function ‘print’: 8 semopen_pth.c:47: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’ 9 root@linux:/mnt/hgfs/C_libary# 10 注:產生了一些警告,先不管這些,看看是否能運行11 root@linux:/mnt/hgfs/C_libary# ./semopen_pth sem12 pthread_id is -1217336464, get the resource13 now,the semaphore value is 214 pthread_id is -1225729168, get the resource15 now,the semaphore value is 116 pthread_id is -1234121872, get the resource17 now,the semaphore value is 018 finish, pthread_id is -121733646419 finish, pthread_id is -122572916820 finish, pthread_id is -123412187221 pthread_id is -1242514576, get the resource22 now,the semaphore value is 223 pthread_id is -1250907280, get the resource24 now,the semaphore value is 125 finish, pthread_id is -124251457626 finish, pthread_id is -125090728027 root@linux:/mnt/hgfs/C_libary# 

有名信號燈同步多進程:

  unix網絡編程第二卷,如是說不同進程(不管是否彼此有無親緣關系),他們都可以訪問同一個信號燈,只是需要在sem_open的時候傳入的名字是一樣就行。在有親緣關系時,Posix中的fork如是描述,在父進程中打開的任何信號燈,仍應在子進程中打開。

示例代碼:

1 /*semopen_pro.c*/ 2 #include <stdio.h> 3 #include <semaphore.h> 4 #include <fcntl.h> 5 #include <unistd.h> 6 #include <sys/types.h> 7 #include <sys/wait.h> 8  9 void print();10 sem_t * sem;                                                                                                    11 12 int main(int argc,char * argv[])13 { 14         int n=0,j;15         pid_t pid;16 17         if(argc != 2)18         { 19                 printf("Usage:%s name.\n",argv[0]);20                 exit(0);21         }22 23         //該信號燈不會因為不同進程而不同。24         sem=sem_open(argv[1],O_CREAT,0644,3);25         while(n++<5)26         { 27                 pid = fork();28                 if(pid == 0)29                 { 30                         sem_wait(sem);31                         print();32                         sleep(1);33                         sem_post(sem);34                         printf("finish,the pid is %d\n",getpid());35                         exit(0);36                 }37         }38 39         j=0;40         41         //等待所有子進程退出42         while(j++<5)43            wait(NULL);44         sem_close(sem);45         sem_unlink(argv[1]);46         return 0;47 }48                                                                                                                                                                                                        49 void print()50 { 51         int value;52         printf("pid is %d, get the resource\n",getpid());53         sem_getvalue(sem,&value);54         printf("now,the semaphore value is %d\n",value);55 }

編譯并執行:

1 root@linux:/mnt/hgfs/C_libary# gcc -o semopen_pro semopen_pro.c 2 semopen_pro.c: In function ‘main’: 3 semopen_pro.c:19: warning: incompatible implicit declaration of built-in function ‘exit’ 4 semopen_pro.c:34: warning: incompatible implicit declaration of built-in function ‘exit’ 5 /tmp/ccUECdL7.o: In function `main': 6 semopen_pro.c:(.text+0x5d): undefined reference to `sem_open' 7 semopen_pro.c:(.text+0x81): undefined reference to `sem_wait' 8 semopen_pro.c:(.text+0x9f): undefined reference to `sem_post' 9 semopen_pro.c:(.text+0x107): undefined reference to `sem_close'10 semopen_pro.c:(.text+0x117): undefined reference to `sem_unlink'11 /tmp/ccUECdL7.o: In function `print':12 semopen_pro.c:(.text+0x14e): undefined reference to `sem_getvalue'13 collect2: ld returned 1 exit status14 注:sem_XXX函數不是標準庫函數,鏈接時需要指定庫-lrt or -pthread.15 root@linux:/mnt/hgfs/C_libary# gcc -lrt -o semopen_pro semopen_pro.c16 semopen_pro.c: In function ‘main’:17 semopen_pro.c:19: warning: incompatible implicit declaration of built-in function ‘exit’18 semopen_pro.c:34: warning: incompatible implicit declaration of built-in function ‘exit’ 19 root@linux:/mnt/hgfs/C_libary# ./semopen_pro sem20 pid is 5262, get the resource21 now,the semaphore value is 222 pid is 5263, get the resource23 now,the semaphore value is 124 pid is 5264, get the resource25 now,the semaphore value is 026 finish,the pid is 526227 pid is 5265, get the resource28 now,the semaphore value is 029 finish,the pid is 526330 pid is 5266, get the resource31 now,the semaphore value is 032 finish,the pid is 526433 finish,the pid is 526534 finish,the pid is 526635 root@linux:/mnt/hgfs/C_libary# 

基于內存的信號燈同步多線程:

1 sem_init() 2 功能:初始化信號燈。 3 頭文件:#include <semaphore.h> 4 函數原型:int sem_open(sem_t * sem,int shared,unsigned int value); 5 參數:sem為信號燈指針,shared是指同步多線程還是多進程(0:多線程,其他:多進程),value為信號量值 6 返回值:成功時,返回0,失敗時,返回-1 7  8 sem_destroy() 9 功能:關閉信號10 頭文件:#include <semaphore.h>11 函數原型:int sem_destroy(sem_t * sem)12 參數:sem為信號燈的指針13 返回值:成功時,返回0,失敗,-1

示例代碼:

1 /*seminit_pth*/ 2 #include <stdio.h> 3 #include <semaphore.h> 4 #include <fcntl.h> 5 #include <pthread.h> 6                                                                                                      7 void print(); 8 void * thread_function(void *arg); 9 sem_t sem;10                                                                                                     11 int main(int argc,char * argv[])12 { 13         int n=0;14         pthread_t tid;15         //init semaphore16         sem_init(&sem,0,3);17         while(n++<5)18         { 19                 if((pthread_create(&tid,NULL,thread_function,NULL))!=0)20                 { 21                        printf("can't create pthread.\n");22                         exit(0);23                 }24         }25         pthread_join(tid,NULL);26         sem_destroy(&sem);27         return 0;28 }29                                                                                                     30 void * thread_function(void *arg)31 { 32         sem_wait(&sem);33         print();34         sleep(1); //35         sem_post(&sem);36         printf("finish, pthread_id is %d\n",pthread_self());37 }38                                                                                                    39 void print()40 { 41         int value;42         printf("pthread_id is %d, get the resource\n",pthread_self());43         sem_getvalue(&sem,&value);44         printf("now,the semaphore value is %d\n",value);45 }

編譯運行:

1 root@linux:/mnt/hgfs/C_libary# gcc -lrt -o seminit_pth seminit_pth.c 2 seminit_pth.c: In function ‘main’: 3 seminit_pth.c:21: warning: incompatible implicit declaration of built-in function ‘exit’ 4 seminit_pth.c: In function ‘thread_function’: 5 seminit_pth.c:35: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’ 6 seminit_pth.c: In function ‘print’: 7 seminit_pth.c:41: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘pthread_t’ 8 root@linux:/mnt/hgfs/C_libary#  9 root@linux:/mnt/hgfs/C_libary# ./seminit_pth10 pthread_id is -1224959120, get the resource11 now,the semaphore value is 212 pthread_id is -1233351824, get the resource13 now,the semaphore value is 114 pthread_id is -1241744528, get the resource15 now,the semaphore value is 016 finish, pthread_id is -122495912017 finish, pthread_id is -123335182418 finish, pthread_id is -124174452819 pthread_id is -1250137232, get the resource20 now,the semaphore value is 221 pthread_id is -1216566416, get the resource22 now,the semaphore value is 123 finish, pthread_id is -125013723224 finish, pthread_id is -121656641625 root@linux:/mnt/hgfs/C_libary# 

 

 

作者:PoleStar
來源鏈接:https://www.cnblogs.com/polestar/archive/2012/04/18/2455519.html

贊(96)
未經允許不得轉載:>貴州網站建設公司 » IPC通信:Posix信號燈
国产欧美精品