1

以下のコードでは、各スレッドから配列に要素を挿入できるかどうかを確認しようとしています。期待どおりに動作しています。しかし、どのような状況でここで競合状態が発生する可能性があるのだろうか。ここで揮発性またはセマフォが本当に必要ですか? セマフォと揮発性キーワードを削除しようとしましたが、それでも機能します。ここでも競合状態のシナリオを誘発して見たいと思います。同じ行で、各スレッドからノードを作成し、すべてのノードをリンクされたリストに入れることはできますか? これらはすべて架空のシナリオです..!!

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include "small_appl.h"

void * thread_func(void * arg);

int itr=0;
volatile int idx=0; //array index variable
sem_t sem1;
int arr_th[5];      //array where each thread will insert an element

int func_pointed(int a,int num_t)
{
    pthread_t arr_thr[num_t];
    int iter;
     //create threads
     for(iter=0;iter<num_t;iter++)
     {
        pthread_create(&arr_thr[iter],NULL,thread_func,(void *)a);
     }

     for (iter=0;iter<num_t;iter++)
     {
         pthread_join(arr_thr[iter],NULL);
     }
}

int main(void)
{
    int ip1=5,ip2=10,rev;

    rev=sem_init(&sem1,0,0);
    s_type dev_s={
                    .f_ptr=func_pointed,
                    .str="Diwakar",
                    .val=5
                 };

    //initialize semaphore to 1
    sem_post(&sem1);    

    func_aux(ip1,dev_s);

    for(rev=0;rev<5;rev++)
    {
    printf("array : %d    ",arr_th[rev]);
    }

}

void * thread_func(void * arg)
{
    sem_wait(&sem1);
    printf("Got sema\n");
    arr_th[idx]=itr;
    idx++; itr++;
    printf("Releasing sema\n");
    sem_post(&sem1);

    sleep(5);
}
4

2 に答える 2

1

volatile は、変数がいつでも変更できることをコンパイラに指示します。これは、変数へのすべての参照がメモリからの読み取りにつながる必要があることを意味します (レジスタ内の値のコピーを再利用しないでください)。

volatile int i;
if(i==0) return
if(i==1) ...

キーワードがそこにない場合volatile、コンパイラは変数を一度レジスタに読み込み、0 と 1 をチェックする可能性があります。

メインプログラムで idx 変数がこのように特定の値になるのを待つ場合は、それを にする必要がありますvolatile

while(idx==10);

揮発性はスレッドセーフにはなりません。これは別の問題です。実際、コードのそのセクションを保護するため、読み取りごとに idx が変更されることはないと考えられるため、volatile は必要ありません。

競合状態を生成したい (分割されているコードのセクションを検出する) 場合は、2 つの別々の命令でインクリメントする 2 つの値を設定し、これを連続した while ループで行うことをお勧めします (スリープしない! スリープすると、クリティカル セクションが分割されている)。メイン ループでは、値が等しいかどうかを継続的にチェックします (ここでも、スリープ状態ではありません)。それらが等しくない場合、コードの 2 つのセクションの 1 つが分割されています。また、アセンブリを見て、コンパイラが何かを最適化していないことを確認してください。

于 2013-08-23T06:02:43.713 に答える