【Linux】プロセス間同期(プロセス間反発ロック、ファイルロック)
5227 ワード
一、反発量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、プロセス間反発量操作コード例:
二、ファイルロック
fcntl関数を使用してファイルロックを実現します.操作ファイルのプロセスがロックを取得していない場合は開くことができますが、read、write操作は実行できません.
fcntl関数:ファイルアクセス制御プロパティを取得、設定します.
パラメータ2:
F_SETLK(struct flock *);ファイルロックの設定(trylock)
F_SETLKW(struct flock*);ファイルロックW---waitの設定
F_GETLK(struct flock*);ファイルロックの取得
パラメータ3:
プロセス間ファイルロックコードの例:
プロセス間では、反発ロックを使用して同期の目的を達成することもできます.ただし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;
}