0

私を助けてくれてありがとう、スレッドセーフな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;
           }
        }

    }
4

2 に答える 2

1

スレッドセーフではありません。たとえば、登録部分では、次の行が最終的に問題になります。

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

スレッド 1 が行 1 を実行し、行 2 を実行する前にコンテキストの切り替えが発生した場合、スレッド 2 が実行され、行 1 を実行できます。その時点で、両方のスレッドがpid_arr配列内の同じ位置を「所有」することになります。または、2 行目を最後に実行したものがその位置を所有し、もう一方は配列内のどの位置も所有しません。

于 2012-04-17T23:24:02.733 に答える
0

ファイル スコープまたは外部変数を読み書きするコードは、シリアル化する必要があります。そうしないと、スレッド セーフではありません。

提供されているサンプルはスレッドセーフではありません。

于 2012-04-17T23:30:56.410 に答える