gpt4 book ai didi

c - 多个线程能够同时获得 flock

转载 作者:IT王子 更新时间:2023-10-29 00:06:32 26 4
gpt4 key购买 nike

我的印象是flock(2)是线程安全的,我最近在代码中遇到了这样的情况,其中多个线程能够在同一个文件上获得锁,这些文件都与使用 c api flock 获取独占锁同步。进程25554是一个多线程应用程序,有20个线程,当死锁发生时,锁定同一个文件的线程数是不同的。多线程应用程序 testEvent 是文件的写入者,其中推送是文件的读取者。不幸的是,lsof 不打印 LWP 值,因此我无法找到持有锁的线程。当下面提到的情况发生时,进程和线程都卡在 flock 调用上,如 pid 25569 和 25554 上的 pstackstrace 调用所显示的那样。关于如何进行的任何建议在 RHEL 4.x 中克服这个问题。

我想更新的一件事是 flock 不会一直行为不端,只有当消息的 tx 速率超过 2 mbps 时,我才会遇到 flock 的这个死锁问题,低于 tx 速率的一切都是文件。我一直保持 num_threads = 20, size_of_msg = 1000bytes 不变,只是改变每秒发送的消息数量,从 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 库函数的多线程测试程序。

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;

上面的方法会在测试的main函数中的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 ;
}
}
}

最佳答案

flock(2)被记录为“如果不兼容的锁被另一个进程持有则阻塞” 并且“由 flock() 创建的锁与打开的文件表条目相关联”,因此应该预期同一进程的多个线程的 flock-ed 锁不会交互。(flock 文档没有提到线程)。

因此,解决方案对您来说应该很简单:将一个 pthread_mutex_t 关联到每个支持 flock 的文件描述符,并保护对 flock 与那个互斥体。您也可以使用 pthread_rwlock_t如果您想要读取与写入锁定。

关于c - 多个线程能够同时获得 flock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9462532/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com