1. 程式人生 > >程序如何同步你造了麼

程序如何同步你造了麼

  前言:執行緒如何同步應該知道了吧?不知道也沒關係,可以參考我的這篇部落格:https://www.cnblogs.com/liudw-0215/p/9685498.html,帶你get執行緒同步。那程序如何同步呢?將介紹兩種方式:互斥鎖、檔案鎖,由我娓娓道來。

  一、互斥鎖

   1、介紹

     一看到互斥鎖,就會想到執行緒也用這個方法同步,那怎麼應用到程序呢?

   程序間也可以使用互斥鎖來達到同步的目的。但應在pthread_mutex_init初始化之前修改其屬性為程序間共享

  2、主要函式 

  pthread_mutexattr_t mattr 型別: 用於定義mutex鎖的【屬性】

  (1)pthread_mutexattr_init函式

   初始化一個mutex屬性物件

  int pthread_mutexattr_init(pthread_mutexattr_t *attr);

  (2)pthread_mutexattr_destroy函式

  銷燬mutex屬性物件 (而非銷燬鎖)

  int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);

  (3)pthread_mutexattr_setpshared函式

  修改mutex屬性。

  int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);

  參2pshared取值:

  執行緒鎖:PTHREAD_PROCESS_PRIVATE (mutex的預設屬性即為執行緒鎖,程序間私有)

  程序鎖:PTHREAD_PROCESS_SHARED

  主要就是要用這個pthread_mutexattr_setpshared函式,將屬性設定為程序間共享。

  3、示例程式

  程式如下:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include 
<string.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 i; struct mt *mm; pid_t pid; /* int 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"); */ mm = mmap(NULL, sizeof(*mm), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); 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 < 10; i++) { pthread_mutex_lock(&mm->mutex); (mm->num)++; pthread_mutex_unlock(&mm->mutex); printf("-child----------num++ %d\n", mm->num); } } else if (pid > 0) { for ( i = 0; i < 10; i++) { // sleep(1); pthread_mutex_lock(&mm->mutex); mm->num += 2; pthread_mutex_unlock(&mm->mutex); printf("-------parent---num+=2 %d\n", mm->num); } wait(NULL); } pthread_mutexattr_destroy(&mm->mutexattr); //銷燬mutex屬性物件 pthread_mutex_destroy(&mm->mutex); //銷燬mutex munmap(mm,sizeof(*mm)); //釋放對映區 return 0; }
View Code

  二、檔案鎖

  1、fcntl函式

  檔案鎖的實現主要就是通過fcntl函式來實現的,所以先來介紹這個函式。

  功能:藉助 fcntl函式來實現鎖機制。 操作檔案的程序沒有獲得鎖時,可以開啟,但無法執行readwrite操作。

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

  引數說明:

  引數1:檔案描述符

  引數2:

  F_SETLK (struct flock *) 設定檔案鎖(相當於trylock,不成功直接返回

  F_SETLKW (struct flock *) 設定檔案鎖(相當於lock,不成功一直阻塞W --> wait

  F_GETLK (struct flock *) 獲取檔案鎖

  struct flock {

              ...

              short l_type;     鎖的型別:F_RDLCK F_WRLCK F_UNLCK

              short l_whence;   偏移位置:SEEK_SETSEEK_CURSEEK_END

              off_t l_start;    起始偏移:1000

              off_t l_len;      長度:0表示整個檔案加鎖

              pid_t l_pid;      持有該鎖的程序ID(F_GETLK only)

              ...

         };

  2、示例程式

  程式如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.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;
}
View Code

  總結:喜歡的幫忙推薦一下,在此謝過了;歡迎評論,交流與學習