Я тестирую, если блокировка файлового дескриптора из другого потока затронет основной поток.Какова область действия flock()?
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
//#include <share.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
void *print_message_function(void *ptr);
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
int main (int argc, char * const argv[]) {
pthread_t thread1, thread2;
const char *message1 = "Thread 1";
const char *message2 = "Thread 2";
int iret1, iret2;
iret2 = pthread_create(&thread2, NULL, print_message_function, (void*) message1);
if(iret2)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);
fflush(stdout);
exit(EXIT_FAILURE);
}
printf("pthread_create() for thread 2 returns: %d\n",iret2);
pthread_mutex_lock(&mut);
sleep(1);
std::cout<<"Enter any key:"<<std::endl;
std::cin >> input;
if (fd2 = open("file1", O_RDWR | O_CREAT | O_TRUNC, 0700 | 0x10) == -1)
{
perror("Cannot open file 2.\n");
fflush(stdout);
}
else
{
printf("File was opened 2!!\n");
fflush(stdout);
if(flock(fd2, LOCK_NB | LOCK_EX)==0)
{
printf("THE FILE WAS LOCKED 2.\n");
}
else if(errno == EAGAIN)
{
printf("The file is locked 2. Resource temporarily unavailable.\n");
}
}
pthread_mutex_unlock(&mut);
close(fd2);
std::cout<<"File closed."<<std::endl;
std::cin >> input;
return 0;
}
void *print_message_function(void *ptr)
{
char *message;
message = (char *) ptr;
printf("%s \n", message);
fflush(stdout);
int fd1;
if ((fd1 = open("file1", O_RDWR | O_CREAT | O_TRUNC, 0700 | 0x10)) == -1)
{
perror("thread: Cannot open file 1.\n");
fflush(stdout);
//std::cin >> input;
}
else
{
printf("File was opened 1!!\n");
fflush(stdout);
if(flock(fd1, LOCK_NB | LOCK_EX)==0)
{
printf("THE FILE WAS LOCKED 1.\n");
}
else if(errno == EAGAIN)
{
printf("The file is locked 1. Resource temporarily unavailable.\n");
}
}
pthread_mutex_lock(&mut);
pthread_mutex_unlock(&mut);
printf("End of thread.\n");
}
Выход:
[Session started at 2014-11-26 17:46:16 +0000.]
pthread_create() for thread 2 returns: 0
Thread 1
File was opened 1!!
THE FILE WAS LOCKED 1.
Enter any key:
1
File was opened 2!!
THE FILE WAS LOCKED 2.
File closed.
End of thread.
Я не понимаю, почему стая() используется внутри нити не мешает паствы() используется в основном потоке получать блокировку.
От человека странице Linux:
Блокировки, созданные паствы() связаны с открытым описанием файла (см открыт (2)). Это означает, что дубликаты файловых дескрипторов (созданных , например, fork (2) или dup (2)) относятся к одной и той же блокировке, и этот замок может быть изменен или выпущен с использованием любого из этих дескрипторов. Кроме того, блокировка освобождается либо явной операцией LOCK_UN на любом из этих дублирующих дескрипторов, либо когда все такие дескрипторы были закрыты.
возможно дубликат [несколько потоков, способных получить паству в то же время] (http://stackoverflow.com/questions/9462532/multiple-threads-able-to-get-flock -та-то же самое время) – pilcrow
@pilcrow, а не обман. В вопросе, на который вы ссылаетесь, различные потоки используют один и тот же файловый дескриптор (или, если нет, то ни один из ответов не является удовлетворительным). В этом случае они открывают отдельные дескрипторы в одном файле. В документах 'flock()' s на разных дескрипторах, открытых в одном файле, действительно блокируют друг друга. –
Немного странно, что 'print_message_function()' блокирует и разблокирует мьютекс в конце, но не выполняет какую-либо свою работу в рамках мьютекса. Является ли поведение отличным, если вы выполняете хотя бы 'flock()', удерживая мьютекс (как это уже делает другой поток)? Примечание: вам нужно переместить «sleep()» основного потока из его критического раздела. –