linux操作系统之信号量、互斥量在进程间的同步、文件锁

(1)信号量:进化版的互斥量

         多个线程间对某个对象的部分数据进行共享,使用互斥锁是没有办法实现的,只能将整个数据对象锁住。这样虽然达到了多线程操作数据共享的目的,却导致线程并发性下降。

         信号量:相对折中的一个处理方式,既能保证同步,数据不混乱,又能提高线程开发。

(2)信号量相关函数

          sem_t类型,用来定义信号量。虽然是结构体,使用的时候可以当做整数看待(类似文件描述符)。

           规定信号量不能小于0,信号量的初值,决定了占用信号量的线程的个数。

          头文件在

           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)使用进程锁完成同步

linux操作系统之信号量、互斥量在进程间的同步、文件锁_第1张图片

                linux操作系统之信号量、互斥量在进程间的同步、文件锁_第2张图片

                             linux操作系统之信号量、互斥量在进程间的同步、文件锁_第3张图片

(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)进程间文件锁

     linux操作系统之信号量、互斥量在进程间的同步、文件锁_第4张图片

(7)多线程中,能否使用文件锁?

                   多线程之间共享文件描述符,而给文件加锁,是通过修改文件描述符所指向的文件结构体中的成员变量来实现的。因此线程之间无法使用文件锁。

你可能感兴趣的:(操作系统)