2012-04-17 109 views
0

谢谢大家的帮助,我分享下面的代码,因为它可以提供4字节的交易/会话ID是线程安全的,或者至少我认为它是:)。它将为16个线程/ 16个进程提供非常可观的唯一ID。 以下是该函数的基本测试,p_no是进程号。线程安全的唯一事务ID

int get_id(int choice, unsigned int pid); 
    int start_(int id); 
    void *print_message_function(void *ptr); 
    void *print_message_function2(void *ptr); 

     unsigned int pid_arr[15][2]; 
    int p_no = 1; 
    int main() 
    { 
     pthread_t thread1, thread2; 
     char *message1 = "Thread 1"; 
     char *message2 = "Thread 2";  
     int iret1, iret2; 
    int s,f; 
     for (s=0;s<15;s++) 
     { 
     for (f=0;f<2;f++) 
     pid_arr[s][f]= 0; 

     } 

     iret1 = pthread_create(&thread1, NULL, print_message_function, (void*) message1); 
     iret2 = pthread_create(&thread2, NULL, print_message_function2, (void*) message2); 

     pthread_join(thread1, NULL); 
     pthread_join(thread2, NULL); 
     exit(0); 
    } 

    void *print_message_function(void *ptr) 
    { 
    int one=0; 

    get_id(1/*register*/,(unsigned int)pthread_self()); 
    while (1) 
    { 

    int ret = get_id(0,(unsigned int)pthread_self()); 
    printf("thread 1 = %u\n",ret); 
    sleep(1); 
    } 

    } 
    void *print_message_function2(void *ptr) 
    { 
    int one=0; 

    get_id(1/*register*/,(unsigned int)pthread_self()); 

    while (1) 
    { 

    int ret = get_id(0,(unsigned int)pthread_self()); 
    printf("thread 2 = %u\n",ret); 
    sleep(1); 
    } 

    } 


    int get_id(int choice, unsigned int pid) 
    { 
    int x; 


     if (choice==1) // thread registeration part 
     { 
      for(x=0;x<15;x++) 
     { 
      if (pid_arr[x][0] == 0) 
      { 
      pid_arr[x][0] = pid;  
      pid_arr[x][1] = ((p_no<<4) | x) << 24; 

      break; 
      } 
     } 

     } 

    int y; 
      for(y=0;y<15;y++) // tranaction ID part 
     { 
      if (pid_arr[y][0]==pid) 
      { 

      if(pid_arr[y][1] >= ((((p_no<<4) | y) << 24) | 0xfffffd)) 
      ((p_no<<4) | x) << 24; 
      else 
      pid_arr[y][1]++; 
      return (unsigned int) pid_arr[y][1]; 
      break; 
      } 
     } 

    } 
+0

对不起,你的问题是什么? – 2012-04-17 23:09:38

+0

这实际上不是问题,我只是分享我迄今为止提供的任何多线程会话导向应用程序的唯一会话ID。 – 2012-04-17 23:17:11

+0

也许会更好地发布http://codereview.stackexchange.com/ – weston 2012-04-18 12:58:04

回答

1

它不是线程安全的。例如,在登记部,以下行会是最终的问题:

1:  if (pid_arr[x][0] == 0) 
     { 
2:  pid_arr[x][0] = pid;  

如果线程1执行第1行,然后将其执行第2行之前发生上下文切换,线程2可以运行并执行线1.这一点,两个线程可以最终“拥有”pid_arr阵列中的相同位置。或者,相反,执行第2行的最后一个将拥有该位置,而另一个将不拥有阵列中的任何位置。

+0

@BagDev:不 - 它不会解决它。最好的办法是只使用同步结构(互斥量,信号量等)来确保你没有竞争条件。锁定免费多线程是非常困难的。 – 2012-04-17 23:34:24

+0

这是对的,如果我在注册部分使用睡眠,这可以安全吗?或仅在注册部分使用互斥锁? – 2012-04-17 23:36:36

+0

@BagDev:从粗略的检查,我认为这将使它线程安全......虽然睡眠不一定是足够的,但您需要某种标志(事件或互斥体会更好)来指示第一个线程完成注册。睡眠本身并不能保证线程真正完成。 – 2012-04-17 23:39:38

0

读取/写入文件范围或外部变量的代码必须被序列化,或者它不是线程安全的。

提供的示例不是线程安全的。