多个线程能够同时获得一群 [英] multiple threads able to get flock at the same time

查看:122
本文介绍了多个线程能够同时获得一群的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是IM pression的羊群(2)是线程下安全起见,我最近,跑过在code,其中多个线程都能够得到上都与使用使用C API羊群获得独占锁的同步同一个文件锁的情况。该过程25554是多线程应用程序,它具有20个线程,当死锁发生具有锁定到同一文件的线程数而变化。在多线程应用程序的 testEvent 的是作家的文件,其中是推的是从文件中读取。不幸的是, lsof的不打印LWP值,因此我无法找到它们是持有锁的线程。当下面提及的条件发生的进程和线程停留在为所显示的羊群呼叫的pstack strace的呼吁PID 25569和25554.如何克服这RHEL 4.x的任何建议

有一件事我想更新的羊群没有表现不好的时候,当邮件的发送速率超过2 Mbps的才把我进入这个僵局问题与羊群,低于发送速率一切文件。我一直在 NUM_THREADS = 20, size_of_msg = 1000bytes不变,只是改变的消息数量TX每秒开始从10条信息100条信息为20 * 1000 * 100 = 2 Mbps的,当我增加消息的数量为150,然后涌向问题发生。

我只是想问问你有什么关于flockfile C API意见。

 须藤lsof的FILENAME.TXT
    COMMAND PID USER FD型器件尺寸节点名称
    推25569根11U REG 253.4 1079 49266853 FILENAME.TXT
    testEvent 25554根27uW REG 253.4 1079 49266853 FILENAME.TXT
    testEvent 25554根28uW REG 253.4 1079 49266853 FILENAME.TXT
    testEvent 25554根29uW REG 253.4 1079 49266853 FILENAME.TXT
    testEvent 25554根30uW REG 253.4 1079 49266853 FILENAME.TXT

在多线程测试程序将调用 write_data_lib_func LIB功能。

 无效*的sendMessage(无效* ARG){为int * numOfMessagesPerSecond =(INT *)ARG;
性病::法院LT&;<执行p线程ID<< pthread_self()&所述;&下;的std :: ENDL;
 而(!terminateTest){
   记录* ER1 =记录:创建();
   er1.setDate(一些数据);   的for(int i = 0; I< = * numOfMessagesPerSecond;我++){
     EC = _write_data_lib_func(* ER1);
     如果(EC!= SUCCESS){
       性病::法院LT&;< 写不成功<<的std :: ENDL;     }   }
   删除ER1;
   睡眠(1);
 } 返回NULL;

上面的方法将在测试的主要功能与pthreads被调用。

 为(i = 0; I< _numThreads ++我){
  RC =在pthread_create(安培;螺纹[I],NULL,那么SendMessage(无效*)及_num_msgs);
  断言(0 == RC);

}

下面是作家/读者源,由于特殊原因,我不想在过程只是剪切和粘贴,作家源将访问多线程

  INT write_data_lib_func(录音* REC){
如果(FD == -1){
    FD =打开(FN,O_RDWR | O_CREAT | O_APPEND,0666);
}
如果(FD> = 0){
   / *一些code * /   如果(群(FD,LOCK_EX)小于0){
     打印一些错误信息;
   }
   其他{
    如果(MAXFILESIZE){
      off_t LEN =了lseek(FD,0,SEEK_END);
      ...
      ...
      ftruncate(FD,0);
      ...
      lseek的(FD,0,SEEK_SET);
   } / *最大尺寸阀芯结束* /
   如果(writev则(FD,REC)小于0){
     打印一些错误信息;
   }   如果(群(FD,LOCK_UN)小于0){
   打印一些错误信息;
   }

在事物的读者一边是没有线程的守护进程。

  INT READDATA(){
    而(真){
      如果(FD == -1){
         FD =打开(文件名,O_RDWR);
      }
      如果(群(FD,LOCK_EX)小于0){
        打印一些错误信息;
        打破;
      }
      如果(N =读(FD,的ReadBuf,readBufSize))≤; 0){
        打印一些错误信息;
        打破;
      }
      如果(关闭< N){
        如果(关闭&下; = 0&放大器;&放大器; N大于0){
          corrupt_file = TRUE;
        }
        如果(了lseek(FD,关正,SEEK_CUR)小于0){
          打印一些错误信息;
        }
        如果(corrupt_spool){
          如果(ftruncate(FD,0)℃,){
             打印一些错误信息;
             打破;
           }
        }
      }
      如果(群(FD,LOCK_UN)℃的)
       打印一些错误信息;
      }
   }
}


解决方案

羊群(2)记录为堵,如果不兼容的锁被另一个持有过程
 并用,所以应该可以预期的羊群()与打开的文件表项关联创建锁即羊群 -ed锁定同一进程唐多个线程T交互。
羊群的文件没有提及线程)。

因此​​,该解决方案应该是简单的为您提供:联想有一个 pthread_mutex_t 羊群 -able文件描述符,保护调用羊群与互斥。您还可以使用 pthread_rwlock_t 如果你想读VS写锁定。

I was under the impression that flock(2) is thread safe, I recently, ran across the case in the code, where multiple threads are able to get a lock on the same file which are all synchronized with the use of obtaining exclusive lock using the c api flock. The process 25554 is multi-threaded app which has 20 threads, the number of threads having lock to the same file varies when the deadlock happens. The multi threaded app testEvent is writer to the file, where was the push is the reader from the file. Unfortunately the lsof does not print the LWP value so I cannot find which are the threads that are holding the lock. When the below mentioned condition happens both the process and threads are stuck on the flock call as displayed by the pstack or strace call on the pid 25569 and 25554. Any suggestions on how to overcome this in RHEL 4.x.

One thing I wanted to update is flock does not misbehave all the time, when the tx rate of the messages is more than 2 mbps only then I get into this deadlock issue with flock, below that tx rate everything is file. I have kept the num_threads = 20, size_of_msg = 1000bytes constant and just varied the number of messages tx per second start from 10 messages to 100 messages which is 20*1000*100 = 2 mbps, when I increase the number of messages to 150 then flock issue happens.

I just wanted to ask what is your opinion about 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

The multithreaded test program that will call the write_data_lib_func lib function.

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;

The above method will be called in the pthreads in the main function of the test.

for (i=0; i<_numThreads ; ++i) {
  rc = pthread_create(&threads[i], NULL, sendMessage, (void *)&_num_msgs);
  assert(0 == rc);

}

Here is the writer/reader source, due to proprietary reasons I did not want to just cut and paste, the writer source will accessed multiple threads in a process

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; 
   } 

In the reader side of things is a daemon process with no threads.

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) is documented as "blocking if an incompatible lock is held by another process" and with "locks created by flock() are associated with an open file table entry", so it should be expected that flock-ed locks by several threads of the same process don't interact. (flock documentation don't mention threads).

Hence, the solution should be simple for you: associate one pthread_mutex_t to every flock-able file descriptor, and protect the call to flock with that mutex. You might also use pthread_rwlock_t if you want a read vs write locking.

这篇关于多个线程能够同时获得一群的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆