muszę rozwijać C++ rutynowego wykonywania tego pozornie trywialne zadanie: stworzyć plik tylko wtedy, gdy nie istnieje jeszcze zrobić nic/błąd podbić.Tworzenie nowego pliku unikanie warunków wyścigu
Ponieważ potrzebuję uniknąć warunków wyścigu, chcę użyć zasady "poproś o wybaczenie, a nie pozwolenie" (tj. Usiłowania zamierzonej operacji i sprawdzenia, czy się udało, w przeciwieństwie do wcześniejszego sprawdzenia warunków wstępnych), co według mojej wiedzy , jest jedyną niezawodną i przenośną metodą do tego celu [Wikipedia article][an example with getline].
Mimo to, nie mogłem znaleźć sposób, aby wdrożyć go w moim przypadku. Najlepsze co mogę wymyślić to otwieranie trybu fstream
w trybie app
(lub fopen
z "a"
), sprawdzanie pozycji wyjściowej za pomocą tellp
(C++) lub ftell
(C) i przerywanie, jeśli taka pozycja nie jest równa zero. Ma to jednak dwie wady, a mianowicie, że jeśli plik istnieje, zostanie zablokowany (choć przez krótki czas) i zmieni się jego data modyfikacji.
Sprawdziłem inne możliwe kombinacje ios_base::openmode
dla fstream
, jak również mode
ciągi fopen
ale nie znalazł opcję, która nadaje się do moich potrzeb. Dalsze wyszukiwanie w standardowych bibliotekach C i C++ oraz Boost Filesystem okazały się bezowocne.
Czy ktoś może wskazać metodę wykonać swoje zadanie w solidnej sposób (bez skutków zabezpieczenia, ma warunków wyścigu) bez konieczności korzystania z funkcji specyficznych dla systemu operacyjnego? Mój specyficzny problem dotyczy systemu Windows, ale preferowane byłyby rozwiązania przenośne.
EDYTOWANIE: Odpowiedź BitWhistlera całkowicie rozwiązuje problem programów C. Mimo to jestem zdumiony, że nie istnieje żadne rozwiązanie idiomatyczne w C++. Każdy z nich używa atrybutu open
z atrybutem O_EXCL
, zgodnie z propozycją Andrew Henle, który jest jednak zależny od systemu operacyjnego (w systemie Windows atrybut ten nosi nazwę _O_EXCL
z dodatkowym podkreśleniem [MSDN]) lub osobno kompiluje plik C11 i łączy go z kodem C++ . Co więcej, otrzymany deskryptor pliku nie może zostać przekonwertowany na strumień z wyjątkiem niestandardowych rozszerzeń (np. GCC __gnu_cxx::stdio_filebuf
). Mam nadzieję, że przyszła wersja C++ zaimplementuje podkatrybut "x"
i ewentualnie także odpowiedni modyfikator dla strumieni plików.
Chcesz uniknąć warunków wyścig pomiędzy kilku nitek lub kilku procesów? – user2807083
Jaki jest twój system operacyjny? POSIX zapewnia ['open (filename, O_CREAT | O_EXCL ...)'] (http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html), aby zrobić to, co chcesz zrobić. –
Win32 API pozwala na to. Wiem to na pewno. –