(1)信號量:進化版的互斥量
? ? ? ? ?多個線程間對某個對象的部分數據進行共享,使用互斥鎖是沒有辦法實現的,只能將整個數據對象鎖住。這樣雖然達到了多線程操作數據共享的目的,卻導致線程并發性下降。
? ? ? ? ?信號量:相對折中的一個處理方式,既能保證同步,數據不混亂,又能提高線程開發。
(2)信號量相關函數
? ? ? ? ? sem_t類型,用來定義信號量。雖然是結構體,使用的時候可以當做整數看待(類似文件描述符)。
? ? ? ? ? ?規定信號量不能小于0,信號量的初值,決定了占用信號量的線程的個數。
? ? ? ? ? 頭文件在<semaphore.h>
? ? ? ? ? ?1)初始化一個信號量:sem_init
? ? ? ? ? ? ? ? ? ? ?int? sem_init(sem_t *sem,int pshared,unsigned int value);
? ? ? ? ? ? ? ? ? ? ? ? ? 參數1:信號量
? ? ? ? ? ? ? ? ? ? ? ? ?參數2:取0表示線程間共享,取1表示進程間
? ? ? ? ? ? ? ? ? ? ? ? ?參數3;信號量初值
? ? ? ? ? ?2)銷毀一個信號量:sem_destroy
? ? ? ? ? ? ? ? ? ?int sem_destroy(sem_t *sem);
? ? ? ? ??3)給信號量加鎖:sem_wait(信號量初值--)
? ? ? ? ? ? ? ? ? ?int sem_wait(sem_t *sem);
? ? ? ? ? 4)給信號量解鎖:sem_post(信號量初值++)
? ? ? ? ? ? ? ? ? ?int sem_post(sem_t *sem);
? ? ? ? ? 5)嘗試對信號量加鎖:sem_trywait
? ? ? ? ? ? ? ? ???int sem_trywait(sem_t *sem);
? ? ? ? ? 6)限時嘗試給信號量加鎖:sem_timedwait
? ? ? ? ? ? ? ? ???int sem_timedwait(sem_t *sem,const struct timespec*abs_timeout);
(3)進程間同步
? ? ? ? ? ? ?進程間也可以通過互斥鎖來達到同步,但必須在pthread_mutex_init初始胡之前,修改其屬性為進程間共享。
? ? ? ? ? ? ? pthread_mutexattr_t mattr類型,用來定義mutex鎖的屬性,修改mutex鎖屬性函數。
? ? ? ? ? ? ? ? ? ?1)初始化一個mutex屬性對象:pthread_mutexattr_init
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int pthread_mutexattr_init(pthread_mutexattr_t *attr);
? ? ? ? ? ? ? ? ? ?2)銷毀一個mutex屬性對象:pthread_mutexattr_destroy
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);?
? ? ? ? ? ? ? ? ? ?3)修改mutex屬性
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr , int pshared);?
? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數2:取值:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?線程鎖:PTHREAD_PROCESS_PRIVATE(mutex默認屬性,進程間私有);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?進程鎖:PTHREAD_PROCESS_SHARED
(4)使用進程鎖完成同步
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
(5)文件鎖
? ? ? ? ? ? ? ? 借助fcntl來實現鎖機制。操作文件的進程沒有獲得鎖時 ,可以打開,但無法執行read/write操作
? ? ? ? ? ? ? ? ? ? ? ? ?fcntl函數:獲取和修改文件訪問控制屬性
? ? ? ? ? ? ? ? ?int fcntl(int fd,int cmd,.../*arg*/);
? ? ? ? ? ? ? ? ? ? ? ? ? 參數2:F_SETLK:設置文件鎖(trylock)? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? F_SETLKW 設置文件鎖(wait)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? F_GETLK 獲取文件鎖
? ? ? ? ? ? ? ? ? ? ? ? ?參數3:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct flock{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.....?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? short l_type;//鎖的類型:F_RDLCK,F_WRLCK,F_UNLCK(解鎖);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? short l_whence;//偏移位置,SEEK_SET,SEEK_CUR,SEEK_END
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? off_t l_start;//起始偏移量
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? off_t l_len;? //加鎖數據的長度,len=0,對整個文件加鎖
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? pid_t l_pid;//持有該鎖的進程ID:(F_GETLK only)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?};
(6)進程間文件鎖
? ? ?
(7)多線程中,能否使用文件鎖?
? ? ? ? ? ? ? ? ? ?多線程之間共享文件描述符,而給文件加鎖,是通過修改文件描述符所指向的文件結構體中的成員變量來實現的。因此線程之間無法使用文件鎖。