linux_ process lock and file lock -pthread_mutexattr_init function -pthread_mutexattr_setpshared function

Continued from the previous article: linux_semaphore function series - semaphore implementation producer consumer model - sem_init function - sem_wait function - sem_post function - sem_trywait function

  Let’s analyze process locks and thread locks today. Process locks need to use the pthread_mutexattr_init function, pthread_mutexattr_destroy function, pthread_mutexattr_setpshared function , and file locks need to use the fcntl function . Let’s start serving:

The catalog of articles published by this blogger on CSDN: My CSDN catalog, as a guide to the types of articles published by bloggers on CSDN

1. Mutex mutex – process lock

  Mutex locks can also be used between processes to achieve the purpose of synchronization. But before pthread_mutex_init is initialized, modify its attributes to be shared between processes. The attribute modification functions of mutex mainly include the following.
  pthread_mutexattr_t mattr type: used to define the [attribute] of the mutex lock

1.1.pthread_mutexattr_init function

Function role:
  initialize a mutex attribute object.
Header file:
  #include <pthread.h>
Function prototype:
  int pthread_mutexattr_init(pthread_mutexattr_t *attr);
Function parameters:
  attr: mutex attribute object to be initialized
Return value:
  success: return 0;
  failure: return non-zero.
Notice:

1.2.pthread_mutexattr_destroy function

Function:
  Destroy the mutex attribute object (instead of destroying the lock).
Header file:
  #include <pthread.h>
Function prototype:
  int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
Function parameters:
  attr: mutex attribute object to be destroyed
Return value:
  success: return 0;
  failure: return non-zero
Note:

1.3.pthread_mutexattr_setpshared function

Function role:
  modify the mutex attribute.
Header file:
  #include <pthread.h>
Function prototype:
  int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
Function parameter:
  attr: mutex attribute object
  pshared: can be set as process lock or thread lock
    Thread lock value: PTHREAD_PROCESS_PRIVATE (mutex The default attribute is the thread lock, which is private between processes)
    Process lock value: PTHREAD_PROCESS_SHARED
Return value:
  success: return 0;
  failure: return non-0

1.4. Inter-process mutex example

Mutex is used between processes to achieve synchronization, the code is as follows:

#include <fcntl.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/wait.h>
struct mt {
    
    
    int num;
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexattr;
};

int main(void)
{
    
    
    int fd, i;
    struct mt *mm;
    pid_t pid;

    fd = open("mt_test", O_CREAT | O_RDWR, 0777);
    ftruncate(fd, sizeof(*mm));
    mm = mmap(NULL, sizeof(*mm), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    close(fd);
    unlink("mt_test");
    memset(mm, 0, sizeof(*mm));

    pthread_mutexattr_init(&mm->mutexattr);                                  //初始化mutex属性对象
    pthread_mutexattr_setpshared(&mm->mutexattr, PTHREAD_PROCESS_SHARED);    //修改属性为进程间共享
    pthread_mutex_init(&mm->mutex, &mm->mutexattr);                          //初始化一把mutex琐

    pid = fork();//创建子进程
	if (pid == 0) 
	{
    
    
	//子进程
        for (i = 0; i < 15; i++) 
		{
    
    
            pthread_mutex_lock(&mm->mutex);//加锁
            (mm->num)++;//修改共享资源
            printf("-child----num++   %d\n", mm->num);
            pthread_mutex_unlock(&mm->mutex);//解锁
            sleep(1);
        }
	} 
	else if (pid > 0)
	 {
    
    
        for ( i = 0; i < 15; i++) 
		{
    
    
            sleep(1);
            pthread_mutex_lock(&mm->mutex);//加锁
            mm->num += 2;//修改共享资源
            printf("-parent---num+=2  %d\n", mm->num);
            pthread_mutex_unlock(&mm->mutex);//解锁
        }
        wait(NULL);//等待回收子进程
    }

    pthread_mutexattr_destroy(&mm->mutexattr);          //销毁mutex属性对象
    pthread_mutex_destroy(&mm->mutex);                //销毁mutex
    munmap(mm,sizeof(*mm));                          //释放映射区
    return 0;
}

2. File lock

  Use the fcntl function to implement the lock mechanism. When the process operating the file does not acquire the lock, it can open it, but cannot perform read and write operations.
  fcntl function: Get and set file access control attributes.
  int fcntl(int fd, int cmd, … /* arg */ );
  refer to 2:
    F_SETLK (struct flock *) set file lock (trylock)
    F_SETLKW (struct flock *) set file lock (lock) W --> wait
    F_GETLK (struct flock *) Get file lock
  parameter 3:
   struct flock {       …       short l_type; lock type: F_RDLCK, F_WRLCK, F_UNLCK       short l_whence; offset position: SEEK_SET, SEEK_CUR, SEEK_END       off_t l_start; start offset: 1000       off_t l_len ; Length: 0 means the entire file is locked       pid_t l_pid; Process ID holding the lock: (F_GETLK only)       ...       };







2.1. Example of inter-process file lock

Multiple processes access the locked file, the code is as follows:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

void sys_err(char *str)
{
    
    
    perror(str); exit(1);
}
int main(int argc, char *argv[])
{
    
    
    int fd;
    struct flock f_lock;

    if (argc < 2) 
    {
    
    
        printf("./a.out filename\n"); exit(1);
    }
    if ((fd = open(argv[1], O_RDWR)) < 0)
        sys_err("open");

    //f_lock.l_type = F_WRLCK;        /*选用写琐*/
    f_lock.l_type = F_RDLCK;          /*选用读琐*/ 

    f_lock.l_whence = SEEK_SET;
    f_lock.l_start = 0;
    f_lock.l_len = 0;               /* 0表示整个文件加锁 */

    fcntl(fd, F_SETLKW, &f_lock);
    printf("get flock\n");
    sleep(10);
    f_lock.l_type = F_UNLCK;
    fcntl(fd, F_SETLKW, &f_lock);
    printf("un flock\n");

    close(fd);	 return 0;
}

  Still follow the " read shared, write exclusive " feature. but! If the process directly operates the file without locking, it can still be accessed successfully, but the data is bound to be confused.

  Q: Can file locks be used in multithreading?
  Answer: The file descriptor is shared among multiple threads, and the locking of the file is realized by modifying the member variables in the file structure pointed to by the file descriptor. Therefore, file locks cannot be used in multithreading.

  The above is the sharing of this time, I hope it will be helpful to everyone, welcome to follow the blogger to learn more new knowledge together!

Guess you like

Origin blog.csdn.net/qq_44177918/article/details/130512742