#include
#include
#include
#include
const char *test_file = "/tmp/test_lock";
int main() {
int file desc;
int byte_count;
char *byte_to_write = "A";
struct flock region_1;
struct flock region_2;
int res;
2. Откройте файловый дескриптор:
file_desc = open(test_file, O_RDWR | O_CREAT, 0666);
if (!file_desc) {
fprintf(stderr, "Unable to open %s for read/write\n", test_file);
exit(EXIT_FAILURE);
}
3. Поместите данные в файл:
for (byte_count = 0; byte_count < 100; byte_count++) {
(void)write(file_desc, byte_to_write, 1);
}
4. Задайте разделяемую блокировку для участка region 1 с 10-го байта по 30-й:
region_1.l_type = F_RDLCK;
region_1.l_whence = SEEK_SET;
region_1.l_start = 10;
region_1.l_len = 20;
5. Задайте исключительную блокировку для участка region_2 с 40-го байта по 50-й:
region_2.l_type = F_WRLCK;
region_2.l_whence = SEEK_SET;
region_2.l_start = 40;
region_2.l_len = 10;
6. Теперь заблокируйте файл:
printf("Process %d locking file\n", getpid());
res = fcntl(file_desc, F_SETLK, ®ion_1);
if (res == -1) fprintf(stderr, "Failed to lock region 1\n");
res = fcntl(file_desc, F_SETLK, ®ion_2);
if (res = fprintf(stderr, "Failed to lock region 2\n");
7. Подождите какое-то время:
sleep(60);
printf ("Process %d closing file\n", getpid());
close(file_desc);
exit(EXIT_SUCCESS);
}
Как это работает
Сначала программа создает файл, открывает его для чтения и записи и затем заполняет файл данными. Далее задаются два участка: первый с 10-го по 30-й байт для разделяемой блокировки и второй с 40-го по 50-й байт для исключительной блокировки. Затем программа выполняет вызов fcntl
для установки блокировок на два участка файла и ждет в течение минуты, прежде чем закрыть файл и завершить работу.
На рис. 7.1 показан этот сценарий с блокировками в тот момент, когда программа переходит к ожиданию.
Рис. 7.1
Сама по себе эта программа не очень полезна. Вам нужна вторая программа lock4.c для тестирования блокировок (упражнение 7.10).
Упражнение 7.10. Тестирование блокировок файла
В этом примере вы напишете программу, проверяющую блокировки разных типов, установленные для различных участков файла.
1. Как обычно, начнем с заголовочных файлов и объявлений:
#include
#include
#include
#include
const char *test_file = "/tmp/test_lock";
#define SIZE_TO_TRY 5
void show_lock_info(struct flock *to_show);
int main() {
int file_desc;
int res;
struct flock region_to_test;
int start_byte;
2. Откройте дескриптор файла:
file_desc = open(test_file, O_RDWR | O_CREAT, 0666);
if (!file_desc) {
fprintf(stderr, "Unable to open %s for read/write", test_file);
exit(EXIT_FAILURE);
}
for (start_byte = 0; start_byte < 99; start_byte += SIZE_TO_TRY) {
3. Задайте участок файла, который хотите проверить:
region_to_test.l_type = F_WRLCK;
region_to_test.l_whence = SEEK_SET;
region_to_test.lstart = start_byte;
region_to_test.l_len = SIZE_TO_TRY;
region_to_test.l_pid = -1;
printf("Testing F_WRLCK on region from %d to %d\n", start_byte, start_byte + SIZE_TO_TRY);
4. Теперь проверьте блокировку файла:
res = fcntl(file_desc, F_GETLK, ®ion_to_test);
if (res == -1) {
fprintf(stderr, "F_GETLK failed\n");
exit(EXIT_FAILURE);
}
if (region_to_test.l_pid != -1) {
printf("Lock would fail. F_GETLK returned:\n");
showlockinfo(®ion_to_test);
} else {
printf("F_WRLCK - Lock would succeed\n");
}
5. Далее повторите тест с разделяемой блокировкой (на чтение). Снова задайте участок файла, который хотите проверить:
region_to_test.l_type = F_RDLCK;
region_to_test.l_whence = SEEK_SET;
region_to_test.l_start = start_byte;
region_to_test.l_len = SIZE_TO_TRY;
region_to_test.l_pid = -1;
printf("Testing F_RDLCK on region from %d to %d\n", start_byte, start_byte + SIZE_TO_TRY);
6. Еще раз проверьте блокировку файла:
res = fcntl(file_desc, F_GETLK, ®ion_to_test);
if (res == -1) {
fprintf(stderr, "F_GETLK failed\n");
exit(EXIT_FAILURE);
}
if (region_to_test.l_pid != -1) {
printf("Lock would fail. F_GETLK returned:\n");
show_lock_info(®ion_to_test);
} else {
printf("F_RDLCK — Lock would succeed\n");
}
}
close(file_desc);
Читать дальше