【Linux】プロセス間同期(プロセス間反発ロック、ファイルロック)


一、反発量mutex
プロセス間では、反発ロックを使用して同期の目的を達成することもできます.ただしpthread_mutex_Initが初期化される前に、その属性をプロセス間共有に変更します.mutexのプロパティ修正関数は主に以下のいくつかあります.
主な応用関数:
               1、pthread_mutexattr_t mutexattrタイプ:反発ロックのプロパティを定義します.
               2、pthread_mutexattr_init関数init関数:mutexプロパティオブジェクトを初期化する
                             int pthread_mutexattr_init(pthread_mutexattr_t *attr);
               3、pthread_mutexattr_destroy関数:ロックを破棄するのではなくmutexプロパティオブジェクトを破棄します.
                              int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
               4、pthread_mutexattr_setpshared関数setpshared関数:mutexプロパティの変更
              int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,int pshared);
パラメータ2:psharedの値:
スレッドロック:PTHREAD_PROCESS_PRIVATE(mutexのデフォルト属性はスレッドロック、プロセス間プライベート)
プロセスロック:PTHREAD_PROCESS_SHARED
5、プロセス間反発量操作コード例:
              
/*
            
*/

#include
#include
#include
#include
#include
#include
#include
#include
#include

struct mt
{
    int num;
    pthread_mutex_t mutex;
    pthread_mutexattr_t mutexattr;
};


int main(void)
{
    
    int i;
    struct mt* mm;

    pid_t pid;

    /*
    //  
    int fd = open("mt_test",O_CREAT|O_RDWR,0777);
    if( fd == -1 ) 
    {
        perror("open file:"); 
        exit(1); 
    }
    ftruncate(fd,sizeof(*mm));
    mm = mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    close(fd);
    unlink("mt_test");
  */

    //  
    mm = mmap(NULL,sizeof(*mm),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);

//    printf("-------before memset------
"); memset(mm,0x00,sizeof(*mm)); // printf("-------after memset------
"); 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<10;i++ ) { pthread_mutex_lock(&mm->mutex); (mm->num)++; printf("-child--------------num++ %d
",mm->num); pthread_mutex_unlock(&mm->mutex); sleep(1); } } else { for( i=0;i<10;i++) { sleep(1); pthread_mutex_lock(&mm->mutex); mm->num += 2; printf("--------parent------num+=2 %d
",mm->num); pthread_mutex_unlock(&mm->mutex); } wait(NULL); } pthread_mutexattr_destroy(&mm->mutexattr); // mutex pthread_mutex_destroy(&mm->mutex); // mutex return 0; }

二、ファイルロック
fcntl関数を使用してファイルロックを実現します.操作ファイルのプロセスがロックを取得していない場合は開くことができますが、read、write操作は実行できません.
fcntl関数:ファイルアクセス制御プロパティを取得、設定します.
                      
        #include 
        #include 

                   int fcntl(int fd, int cmd, ... /* arg */ );

パラメータ2:
                    F_SETLK(struct flock *);ファイルロックの設定(trylock)
                    F_SETLKW(struct flock*);ファイルロックW---waitの設定
                    F_GETLK(struct flock*);ファイルロックの取得
パラメータ3:
                   
             struct flock {
                            ...
                            short l_type;    /* Type of lock: F_RDLCK,
                                                F_WRLCK, F_UNLCK */
                            short l_whence;  /* How to interpret l_start:
                                                SEEK_SET, SEEK_CUR, SEEK_END */
                            off_t l_start;   /* Starting offset for lock */
                            off_t l_len;     /* Number of bytes to lock */
                            pid_t l_pid;     /* PID of process blocking our lock
                                                (F_GETLK only) */
                             ...
           };

プロセス間ファイルロックコードの例:
                   
#include
#include
#include
#include
#include
#include

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
"); 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 = 0; f_lock.l_len = 0; // 0 fcntl(fd,F_SETLKW,&f_lock); printf("get flock
"); sleep(10); f_lock.l_type = F_UNLCK; fcntl(fd,F_SETLKW,&f_lock); printf("un flock
"); close(fd); return 0; }