天天看點

Linux 下c++多線程同步之信号量

操作步驟:

1.建立信号量
		函數: int  semget(key_t  _key ,int  _nsems,int _semflg);
		
		_key  為整型值,使用者可以自己設定
		
		_nsems 表示初始化信号量的個數。比如我們要建立一個信号量,則該值為1.,建立2個就是2。
		
		_semflg  :信号量的建立方式或權限。有IPC_CREAT,IPC_EXCL。
				IPC_CREAT如果信号量不存在,則建立一個信号量,否則擷取。
				IPC_EXCL隻有信号量不存在的時候,新的信号量才建立,否則就産生錯誤。					           

複制

2.P操作(信号量值減一)

3.V操作(信号量值加一)

2和3步驟函數為:

int semop(int semid ,struct sembuf *_sops ,size_t _nsops);

功能:使用者改變信号量的值。也就是使用資源還是釋放資源使用權。
傳回值:成功傳回0,失敗傳回-1;
參數:

   _semid : 信号量的辨別碼。也就是semget()的傳回值。

  _sops是一個指向結構體數組的指針。

 struct   sembuf{
	 nsigned short  sem_num;//第幾個信号量,第一個信号量為0
     short  sem_op;//對該信号量的操作。
     short _semflg;
 };
sem_num:  操作信号在信号集中的編号。第一個信号的編号為0;
sem_op : 如果其值為正數,該值會加到現有的信号内含值中。通常用于釋放所控資源的使用權;如果sem_op的值為負數,而其絕對值又大于信号的現值,操作将會阻塞,直到信号值大于或等于sem_op的絕通常用于擷取資源的使用權;如果     	
sem_op的值為0,則操作将暫時阻塞,直到信号的值變為0。
_semflg IPC_NOWAIT //對信号的操作不能滿足時,semop()不會阻塞,并立即傳回,同時設定錯誤資訊。
IPC_UNDO //程式結束時(不論正常或不正常),保證信号值會被重設為semop()調用前的值。這樣做的目的在于避免程式在異常情況下結束時未将鎖定的資源解鎖,造成該資源永遠鎖定。
nsops:操作結構的數量,恒大于或等于1。           

複制

以上借鑒 信号量 Linux函數 semget();semctl();semop();

信号量阻塞案例

void debugPrint(char *objName, char *objAct, char *objState)
{
#ifdef DEBUG
  if (strlen(objAct) <= 20 && strlen(objAct) <= 15 && strlen(objAct) <= 10)
  {
    printf("%s::DEBUG   %-25.20s %-20.15s %-10.10s\n", POR_NAME, objName, objAct, objState);
  }else
  {
    printf("%s::DEBUG   %-40.35s %-35.30s %-20.20s\n", POR_NAME, objName, objAct, objState);
  }
  
#endif
}
int sem_mutex = 0;
void *semp_thread(void *param)
{
  struct sembuf buf[] = {{0, -1, SEM_UNDO}};
  semop(sem_mutex, buf, 1);
  debugPrint("semp_thread.sem_mutex", "semop P", "-1");
  /*
    線程結束後,傳值出去,
    給pthread_join()的參數2
  */
  sleep(3);
  struct sembuf buf1[] = {{0, 1, SEM_UNDO}};
  semop(sem_mutex, buf1, 1);
  debugPrint("semp_thread.sem_mutex", "semop V", "+1");
}

// semphore
int main()
{
  sem_mutex = semget(123, 1, IPC_CREAT | 0666);
  union semun su;
  su.value = 1;
  semctl(sem_mutex, 0, SETVAL, su);
  // p操作
  struct sembuf buf[] = {{0, -1, SEM_UNDO}};
  semop(sem_mutex, buf, 1);
  debugPrint("main.sem_mutex", "semop P", "-1");
  pthread_t semThreadID = NULL;
  pthread_create(&semThreadID, NULL, semp_thread, NULL);
  sleep(3);

  struct sembuf buf1[] = {{0, 1, SEM_UNDO}};
  semop(sem_mutex, buf1, 1);
  debugPrint("main.sem_mutex", "semop V", "+1");
  pthread_join(semThreadID, NULL);
}           

複制