flock(2)はスレッド セーフであるという印象を受けました。最近、複数のスレッドが同じファイルのロックを取得できるコードのケースに出くわしました。 c api 群れ。プロセス 25554 は、20 個のスレッドを持つマルチスレッド アプリであり、デッドロックが発生すると、同じファイルにロックされているスレッドの数が異なります。マルチスレッド アプリのtestEventはファイルへのライターであり、プッシュはファイルからのリーダーです。残念ながら、lsof
LWP の値が表示されないため、ロックを保持しているスレッドを特定できません。以下の条件が発生すると、プロセスとスレッドの両方が群れの呼び出しで停止しますpstack
。strace
pid 25569 および 25554 を呼び出します。RHEL 4.x でこれを克服する方法についての提案。
私が更新したかったことの 1 つは、メッセージの tx レートが 2 mbps を超える場合に限り、flock は常に誤動作しないということです。その tx レートを下回ると、すべてがファイルになります。num_threads
= 20、 = 1000バイトを一定に保ち、size_of_msg
1秒あたりのメッセージ送信数を10メッセージから100メッセージに変更しました。これは20 * 1000 * 100 = 2 mbpsであり、メッセージ数を150に増やして群れの問題を引き起こします起こります。
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
write_data_lib_func
lib 関数を呼び出すマルチスレッド テスト プログラム。
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;
上記のメソッドは、テストのメイン関数の pthreads で呼び出されます。
for (i=0; i<_numThreads ; ++i) {
rc = pthread_create(&threads[i], NULL, sendMessage, (void *)&_num_msgs);
assert(0 == rc);
}
ここにライター/リーダー ソースがあります。独自の理由により、単にカット アンド ペーストしたくありませんでした。ライター ソースは、プロセス内の複数のスレッドにアクセスします。
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;
}
リーダー側には、スレッドのないデーモン プロセスがあります。
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 ;
}
}
}