线程安全的唯一事务ID

时间:2012-04-17 23:04:50

标签: c multithreading

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

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

    }

2 个答案:

答案 0 :(得分:1)

它不是线程安全的。例如,在注册部分中,以下行最终会成为问题:

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

如果thread1执行第1行然后在执行第2行之前发生了上下文切换,则thread2可以运行并执行第1行。此时,两个线程最终可以“拥有”pid_arr中的相同位置阵列。或者说,执行第2行的最后一个将拥有该位置,而另一个将不拥有数组中的任何位置。

答案 1 :(得分:0)

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

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