发信人: kevintz() 
整理人: mrcloud(2000-10-25 16:19:28), 站内信件
 | 
 
 
                   关于线程锁一个疑问的解答
                                             kevintz 2000.9.8
     网友bbenmi提到一个问题:
         我的程序是多线程的,这些线程要访问一个全局数组 Arr[MAX]。 
         为此我用了一个pthread_mutex_t lock锁 
         每次对这个数组的某个单元(如Arr[5])进行写操作的时候, 
         先  Pthread_mutex_lock(&lock); 
         然后对这个单元写,写完后再 Pthread_mutex_unlock(&lock); 
 
         但是,这样做,每次都是把整个数组给锁住了,非常影响程序的执行效 率。 
 
         后来我就在每个数组单元里加入了一个锁,每次写的时候只加锁相应 
          单元的锁,可是我发现,这样做的结果仍然是整个数组被锁住了。 
 
         请问,有什么办法可以做到: 
         我对某一个单元进行写操作的时候,只是锁这个单元,而其他单元仍然  
         可以进行正常的访问(读和写)? 
 
         谢谢! 
 
     其实锁和数据是没有必然的联系的。下面是我写的一个测试程序。要注意的 是,
 线程不能太多,例如开2000条线程的话,程序会中断,因为计算机的资源你占太 多
 了。这个程序在Red Hat Linux 6.1下通过。
     你可以尝试不同的howlong值,观察lockfailed的次数变化。
 
 #include <sys/times.h>
 #include <pthread.h>
 #include <unistd.h>
 #include <errno.h>
 #include <stdio.h>
 
 #define ARRAYSIZ 4
 #define THRNUM   20
 
 struct element {
         int count;
         pthread_mutex_t lock;
 } Arr[ARRAYSIZ];
 
 pthread_t pthr[THRNUM];
 int lockfailed;
 int lockok;
 int howlong;
 
 void delay()
 {
         int j=howlong;
         while(j--);
 }
 
 void init()
 {
         int i;
         srand(time(NULL));
         lockfailed=0;
         lockok=0;
         for(i=0; i<ARRAYSIZ; i++) {
                 Arr[i].count=0;
                 pthread_mutex_init(&Arr[i].lock, NULL);
         }
 }
 void* run(void* arg)
 {
         int i;
         int j;
         for(i=0; i< 20; i++ ) {
                 j=random();
                 j%=ARRAYSIZ;
 
             again:
                 if(pthread_mutex_trylock(&Arr[j].lock) ) {
                         lockfailed++;
                         goto again;
                 } else
                         lockok++;
 
                 delay();
                 Arr[j].count++;
                 pthread_mutex_unlock(&Arr[j].lock);
         }
         return NULL;
 }
 
 int main(int argc, char* argv[])
 {
         int i;
         int total=0;
         long t1,t2;
         init();
         if(argc == 1)
                 howlong=100000;
         else
                 howlong=atoi(argv[1]);
         printf("howlong=%d\n", howlong);
         time(&t1);
         for(i=0; i<THRNUM; i++) {
                 if( pthread_create(&pthr[i], NULL, run, NULL))
                         exit(1);
         }
         for( i=0; i< THRNUM; i++)
                 pthread_join(pthr[i], NULL);
         for(i=0; i<ARRAYSIZ; i++) {
                 printf("count[%d]=%d\n", i,Arr[i].count);
                 total+=Arr[i].count;
         }
         time(&t2);
         printf("total=%d lockfailed=%d lockok=%d time=%d sec\n",
                 total, lockfailed, lockok, t2-t1);
         exit(0);
 }
  -- If you understand unix, you understand the world.
 If you understand NT, you JUST understand NT.
  ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 61.140.71.100]
  | 
 
 
 |