Ho avuto l'impressione che il codice flock(2) sia thread-safe, di recente ho trovato il caso nel codice, dove più thread sono in grado di ottenere un blocco sullo stesso file che sono tutto sincronizzato con l'uso di ottenere un blocco esclusivo usando il c api flock. Il processo 25554 è un'app multi-thread che ha 20 thread, il numero di thread con lock sullo stesso file varia quando si verifica il deadlock. L'app multi-thread testEvent è writer per il file, dove era il push è il lettore dal file. Sfortunatamente il lsof
non stampa il valore LWP quindi non riesco a trovare quali sono i thread che stanno tenendo il blocco. Quando si verifica la condizione sotto menzionata, sia il processo che i thread sono bloccati nella chiamata del branco come visualizzato dalla chiamata pstack
o strace
sul pid 25569 e 25554. Qualche suggerimento su come superare questo in RHEL 4.x.thread multipli in grado di ottenere il gruppo allo stesso tempo
Una cosa che volevo aggiornare è che il flock non si comporta in modo anomalo tutto il tempo, quando la velocità tx dei messaggi è superiore a 2 Mbps solo allora mi trovo in questo problema di deadlock con flock, al di sotto di tale velocità tutto è file. Ho mantenuto la costante num_threads
= 20, size_of_msg
= 1000bytes e ho appena variato il numero di messaggi tx al secondo a partire da 10 messaggi a 100 messaggi che è 20 * 1000 * 100 = 2 mbps, quando aumento il numero di messaggi a 150 quindi il problema del gregge si verifica
Volevo solo chiedere qual è la tua opinione su flockfile c api.
sudo lsof filename.txt
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
push 25569 root 11u REG 253.4 1079 49266853 filename.txt
testEvent 25554 root 27uW REG 253.4 1079 49266853 filename.txt
testEvent 25554 root 28uW REG 253.4 1079 49266853 filename.txt
testEvent 25554 root 29uW REG 253.4 1079 49266853 filename.txt
testEvent 25554 root 30uW REG 253.4 1079 49266853 filename.txt
Il programma di test multithread che chiamerà la funzione lib write_data_lib_func
.
void* sendMessage(void *arg) {
int* numOfMessagesPerSecond = (int*) arg;
std::cout <<" Executing p thread id " << pthread_self() << std::endl;
while(!terminateTest) {
Record *er1 = Record::create();
er1.setDate("some data");
for(int i = 0 ; i <=*numOfMessagesPerSecond ; i++){
ec = _write_data_lib_func(*er1);
if(ec != SUCCESS) {
std::cout << "write was not successful" << std::endl;
}
}
delete er1;
sleep(1);
}
return NULL;
Il metodo precedente verrà chiamato in pthreads nella funzione principale del test.
for (i=0; i<_numThreads ; ++i) {
rc = pthread_create(&threads[i], NULL, sendMessage, (void *)&_num_msgs);
assert(0 == rc);
}
Qui è la fonte scrittore/lettore, per motivi di proprietà, non volevo solo tagliare e incollare, la fonte scrittore accede più thread in un processo
int write_data_lib_func(Record * rec) {
if(fd == -1) {
fd = open(fn,O_RDWR| O_CREAT | O_APPEND, 0666);
}
if (fd >= 0) {
/* some code */
if(flock(fd, LOCK_EX) < 0) {
print "some error message";
}
else {
if(maxfilesize) {
off_t len = lseek (fd,0,SEEK_END);
...
...
ftruncate(fd,0);
...
lseek(fd,0,SEEK_SET);
} /* end of max spool size */
if(writev(fd,rec) < 0) {
print "some error message" ;
}
if(flock(fd,LOCK_UN) < 0) {
print some error message;
}
Nel lato lettore di cose c'è un processo daemon senza thread.
int readData() {
while(true) {
if(fd == -1) {
fd= open (filename,O_RDWR);
}
if(flock (fd, LOCK_EX) < 0) {
print "some error message";
break;
}
if(n = read(fd,readBuf,readBufSize)) < 0) {
print "some error message" ;
break;
}
if(off < n) {
if (off <= 0 && n > 0) {
corrupt_file = true;
}
if (lseek(fd, off-n, SEEK_CUR) < 0) {
print "some error message";
}
if(corrupt_spool) {
if (ftruncate(fd,0) < 0) {
print "some error message";
break;
}
}
}
if(flock(fd, LOCK_UN) < 0)
print some error message ;
}
}
}
Puoi pubblicare il codice che chiama 'flock'? Un programma di test [semplice] (http://sscce.org) sarebbe bello. – phihag
AFAIK, i blocchi di avviso non garantiscono la coerenza. http://www.gsp.com/cgi-bin/man.cgi?section=2&topic=flock – zengr