天天看點

LINUX信号量線程控制例子

除了上次講的互斥鎖,使用信号量也就是作業系統中所提到的PV原語,也能達到互斥和同步的效果,這就是下面要說的。

           PV原語是對整數計數器信号量sem的操作,一次P操作可使sem減一,而一次V操作可是sem加一。程序(或線程)根據信号量的值來判斷是否對公共資源具有通路權限。當信号量的值大于零或等于零的時候,該程序(或線程)具有對公共資源通路的權限,否則,當信号量的值小于時,該程序(或線程)就會被阻塞,直到信号量的值大于或等于一。                    在LINUX中,實作了POSIX的無名信号量,主要用于線程間的互斥同步,下面将簡單介紹一些函數接口:   sem_init 功能:         用于建立一個信号量,并初始化信号量的值。 函數原型:     int sem_init (sem_t* sem, int pshared, unsigned int value);   int sem_wait       (sem_t* sem); int sem_trywait   (sem_t* sem); int sem_post       (sem_t* sem); int sem_getvalue (sem_t* sem); int sem_destroy   (sem_t* sem);   功能:         sem_wait和sem_trywait相當于P操作,它們都能将信号量的值減一,兩者的差別在 于若信号量的值小于零時,sem_wait将會阻塞程序,而sem_trywait則會立即傳回。         sem_post相當于V操作,它将信号量的值加一,同時發出喚醒的信号給等待的程序 (或線程)。         sem_getvalue 得到信号量的值。         sem_destroy 摧毀信号量。   程式執行個體如下:   #include <stdlib.h>

#include <stdio.h>

#include <pthread.h>

#include <errno.h>

#include <semaphore.h>   #define return_if_fail(p) /

         if(!p) { printf("[%s]:func error!", __func__); return; }   typedef struct _PrivInfo {

         sem_t sem;

         int lock_var;

         time_t end_time;

}PrivInfo;   void  info_init(PrivInfo *thiz);

void *pthread_function1(void *paramthiz);

void *pthread_function2(void *paramthiz);

int main (int argc, char** argv) {

          pthread_t pt_1 = 0;

          pthread_t pt_2 = 0;           int ret = 0;          PrivInfo *thiz = NULL;           thiz = (PrivInfo*)malloc(sizeof(PrivInfo));           if(NULL == thiz) {

           return -1;

          }           info_init(thiz);           ret = pthread_create(&pt_1, NULL, pthread_function1, (void*)thiz);           if(0 != ret) {

                   perror("pthread1 creation failed!"); 

         }

          ret = pthread_create(&pt_2, NULL, pthread_function2,(void*)thiz);           if(0 != ret) {

                   perror("pthread2 creation failed!"); 

         }           pthread_join(pt_1, NULL);

          pthread_join(pt_2, NULL);           sem_destroy(&thiz->sem);

          free(thiz); 

         thiz = NULL;

         return 0;

}   void info_init(PrivInfo *thiz) {

          return_if_fail(&thiz != NULL);           thiz->lock_var = 0;

         thiz->end_time = time(NULL) + 10;          sem_init(&thiz->sem, 0, 1);

         return;

}   void *pthread_function1(void *paramthiz) { 

         int i = 0;          PrivInfo *thiz = (PrivInfo *)paramthiz;          while(time(NULL) < thiz->end_time) {

                  sem_wait(&thiz->sem);

                  printf("thread1 get the lock./n");

                  for(; i<2; i++) {

                           thiz->lock_var ++;

                           sleep(3);

                  }

                  sem_post(&thiz->sem);

                  printf("thread1 unlock./n");

         }

         sleep(1);          pthread_exit(NULL);

}   void *pthread_function2(void *paramthiz) { 

         PrivInfo *thiz = (PrivInfo *)paramthiz;          while(time(NULL) < thiz->end_time) {

                  sem_wait(&thiz->sem);

                  printf("thread2 get the lock. The lock_var = %d./n",                                  thiz->lock_var);

                  sem_post(&thiz->sem);

                  printf("thread2 unlock./n");

                  sleep(3);

         }

         pthread_exit(NULL);

}

繼續閱讀