程序如何同步你造了麼
前言:執行緒如何同步應該知道了吧?不知道也沒關係,可以參考我的這篇部落格: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);
參2:pshared取值:
執行緒鎖:PTHREAD_PROCESS_PRIVATE (mutex的預設屬性即為執行緒鎖,程序間私有)
程序鎖:PTHREAD_PROCESS_SHARED
主要就是要用這個pthread_mutexattr_setpshared函式,將屬性設定為程序間共享。
3、示例程式
程式如下:
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #includeView Code<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; }
二、檔案鎖
1、fcntl函式
檔案鎖的實現主要就是通過fcntl函式來實現的,所以先來介紹這個函式。
功能:藉助 fcntl函式來實現鎖機制。 操作檔案的程序沒有獲得鎖時,可以開啟,但無法執行read、write操作。
原型: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_SET、SEEK_CUR、SEEK_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
總結:喜歡的幫忙推薦一下,在此謝過了;歡迎評論,交流與學習