Linux信号量之用户态信号量(Posix信号量->无名信号量)
生活随笔
收集整理的這篇文章主要介紹了
Linux信号量之用户态信号量(Posix信号量->无名信号量)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
相關API:
1、初始化信號量
int sem_init(sem_t* sem,int pshared,unsigned int value); //pshared為信號量最多由幾個進程共享。Linux中只能取o。value一般為1,表示資源可用,為o表示不可用2、等待信號量,如果信號量為0則等待,如果信號量大于0則返回,同時對值做減1操作
int sem_wait(sem_t* sem); int sem_trywait(sem_t* sem); int sem_timedwait(sem_t* sem,const struct timespec* abs_timeout);3、釋放信號量,信號量加1操作
int sem_post(sem_t* sem);4、獲取信號量的值
int sem_getvalue(sem_t* sem,int* sval);5、銷毀信號量
int sem_destroy(sem_t* sem);信號量在進程是以有名信號量進行通信的,在線程是以無名信號進行通信的。
由于linux還沒有實現(xiàn)進程間的通信,只實現(xiàn)了無名信號量,所以在sem_init的第二個參數(shù)要為0。
在多線程間的同步是可以通過有名信號量也可通過無名信號,但是一般情況線程的同步是無名信號量,無名信號量使用簡單,而且sem_t存儲在進程空間中,有名信號量必須LINUX內核管理,由內核結構struct ipc_ids存儲,是隨內核持續(xù)的,系統(tǒng)關閉,信號量則刪除,當然也可以顯示刪除,通過系統(tǒng)調用刪除,消息隊列,信號量,內存共享,這幾個都是一樣的原理。
使用信號量解決多線程搶占資源的問題
#include <stdio.h> #include <stdlib.h> #include <unisd.h> #include <pthread.h> #include <string.h> #include <semaphore.h>char buffer[1024];sem_t sem;//聲明信號量void *pthfun(){for(int ii=0;ii<3;ii++){printf("%d:%ld:lock...\n",time(0),(long)arg);sem_wait(&sem);//加鎖printf("%d:%ld:lock ok\n",time(0),(long)arg);//操作共享的全局變量sprintf(buffer,"%d:%ld,%d",time(0),pthread_self(),ii);sleep(5);sem_post(&sem);//解鎖printf("%d:%ld:unlock\n",time(0),(long)arg);usleep(100);} }int main(){sem_init(&sem,0,1);pthread_t pthid1,pthid2;pthread_creat(&pthid1,NULL,pthfun,(void*)1);pthread_creat(&pthid2,NULL,pthfun,(void*)2);pthread_join(pthid1,NULL);pthread_join(pthid2,NULL);sem_destroy(&sem);//銷毀信號量return 0; }互斥鎖和信號量實現(xiàn)高速緩存
// 本程序演示用互斥鎖和信號量實現(xiàn)高速緩存。#include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <vector> #include <semaphore.h> using namespace std;int mesgid=1; // 消息的記數(shù)器。 // 緩存消息的結構體。 struct st_message{int mesgid;char message[1024]; } stmesg;vector<struct st_message> vcache; // 用vector容器做緩存。 sem_t sem; // 聲明信號量。 pthread_mutex_t mutex;// 聲名并初始化互斥鎖。// 消費者、出隊線程主函數(shù)。 void *outcache(void *arg){struct st_message stmesg;while (true){while (vcache.size() == 0){sem_wait(&sem); // 如果緩存中沒有數(shù)據(jù),等待信號。printf("%ld wait ok.\n",pthread_self());}pthread_mutex_lock(&mutex); // 加鎖。if (vcache.size() == 0) // 判斷緩存中是否有數(shù)據(jù)。{pthread_mutex_unlock(&mutex); continue; // 解鎖,continue。}// 從緩存中獲取第一條記錄,然后刪除該記錄。memcpy(&stmesg,&vcache[0],sizeof(struct st_message));vcache.erase(vcache.begin());pthread_mutex_unlock(&mutex); // 解鎖。// 以下是處理業(yè)務的代碼。printf("phid=%ld,mesgid=%d\n",pthread_self(),stmesg.mesgid);usleep(100);} } // 生產(chǎn)者、把生產(chǎn)的數(shù)據(jù)存入緩存。 void incache(int sig){struct st_message stmesg;emset(&stmesg,0,sizeof(struct st_message));pthread_mutex_lock(&mutex); // 加鎖。// 生產(chǎn)數(shù)據(jù),放入緩存。stmesg.mesgid=mesgid++; vcache.push_back(stmesg);stmesg.mesgid=mesgid++; vcache.push_back(stmesg);stmesg.mesgid=mesgid++; vcache.push_back(stmesg);stmesg.mesgid=mesgid++; vcache.push_back(stmesg);stmesg.mesgid=mesgid++; vcache.push_back(stmesg);stmesg.mesgid=mesgid++; vcache.push_back(stmesg);pthread_mutex_unlock(&mutex); // 解鎖。sem_post(&sem); // 信號加1。sem_post(&sem); // 信號加1。sem_post(&sem); // 信號加1。sem_post(&sem); // 信號加1。sem_post(&sem); // 信號加1。sem_post(&sem); // 信號加1。 }int main(){signal(15,incache); // 接收15的信號,調用生產(chǎn)者函數(shù)。sem_init(&sem,0,0); // 初始化信號量。pthread_mutex_init(&mutex,NULL); // 初始化互斥鎖。pthread_t thid1,thid2,thid3;pthread_create(&thid1,NULL,outcache,NULL);pthread_create(&thid2,NULL,outcache,NULL);pthread_create(&thid3,NULL,outcache,NULL);pthread_join(thid1,NULL);pthread_join(thid2,NULL);pthread_join(thid3,NULL);return 0; }總結
以上是生活随笔為你收集整理的Linux信号量之用户态信号量(Posix信号量->无名信号量)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux信号量之内核信号量
- 下一篇: 报错:“-bash: git: 未找到命