2016-10-17 1 views
0

2つのスレッドT1T2を使用して数値を出力したいとします。 T1は1,2,3,4,5のような番号を印刷し、次にT2は6,7,8,9,10を印刷し、T1を開始してからT2を続ける必要があります。 1....100から印刷する必要があります。私には2つの質問があります。linux 2で2つのスレッドをスケジューリングすると、数字のパターンが出力されます

  1. スレッドとグローバル変数を使用してタスクを完了するにはどうすればよいですか?
  2. Linuxでスレッドを希望の順序でスケジュールするにはどうすればよいですか?
+2

の可能性のある重複[Cスレッドプログラミング - 共有変数をインクリメント(http://stackoverflow.com/questions/1533390/c-threaded-programming-incrementing-a-shared-variable ) – LPs

答えて

1

どのようにスレッドを希望の順序でLinuxでスケジュールできますか?

スレッドのスケジューリング順序に影響を与えるために、mutexや条件変数などのロックプリミティブを使用する必要があります。あるいは、スレッドを独立してオーダーで動作させる必要があります。

スレッドとグローバル変数を使用してタスクを完了するにはどうすればよいですか?

変数が1つしか使用できない場合、mutexは使用できません(2番目の変数になります)。したがって、最初に行う必要があるのは、変数をアトミックに宣言することです。それ以外の場合、コンパイラは、あるスレッドが他のスレッドによって加えられた変更を認識しないようにコードを最適化することができます。そして、あなたが望むような簡単なコードの場合は、register on変数をキャッシュすることによってそうするでしょう。 std::atomic_intを使用してください。 volatile intを使用するアドバイスがありますが、現在はstd::atomic_intが望ましいものを指定するためのより直接的な方法です。

mutexを使用することはできません。したがって、スレッドを待機させることはできません。彼らはCPUを無駄に使い果たしてしまいます。しかし、それはタスクのためにOKと思われる。したがって、スピンロックを作成する必要があります。スレッドは常に値をチェックするループで待機します。 value % 10 < 5の場合、最初のスレッドはループを壊してインクリメントします。そうでない場合は、2番目のスレッドがジョブを実行します。

質問は宿題のように見えるので、私はここにコードサンプルを示していないので、あなた自身でそれを書く必要があります。

0

スレッドとグローバル変数を使用してタスクを完了するにはどうすればよいですか?

あなたがLinuxを使用している場合は、Cプログラミング言語のスレッドのためPOSIXライブラリを使用することができます。ライブラリは<pthread.h>です。しかし、代わりに、移植可能で比較的非侵入型のライブラリで、gccg++でよくサポートされていて、MSVCの(旧バージョンの)ライブラリはopenMPです。

標準CおよびC++ではありませんが、OpenMP自体は標準です。

どのようにスレッドを希望の順序でLinuxでスケジュールできますか?

印刷を行うには、2つのスレッドでアクセスできるグローバル変数が必要です。両方のスレッドが交互にグローバル変数variableにアクセスし、操作を実行します(incrementおよびprint)。ただし、desired orderを達成するには、mutexが必要です。ミューテックスは相互排除セマフォーであり、一度に1つのロッカーしか許可しないセマフォの特殊な変形です。これは、リソースのインスタンス(global variable in your case)があり、そのリソースが2つのスレッドによって共有されている場合に使用できます。そのミューテックスをロックした後のスレッドは、リソースのインスタンスへの排他的なアクセスを持つことができ、その操作を完了した後、スレッドは他のスレッドのためにミューテックスを解放する必要があります。

<pthread.h>のスレッドとmutexは、hereから開始できます。

問題の解決策の1つがこのプログラムである可能性があります。しかし、私はあなた自身がそれを試してみることを提案し、次に私の解決策を見てください。

#include <stdio.h> 
#include <pthread.h> 
#include <unistd.h> 

pthread_mutex_t lock; 
int variable=0; 

#define ONE_TIME_INC 5 
#define MAX 100 

void *thread1(void *arg) 
{ 
while (1) { 
    pthread_mutex_lock(&lock); 
    printf("Thread1: \n"); 
    int i; 
    for (i=0; i<ONE_TIME_INC; i++) { 
     if (variable >= MAX) 
      goto RETURN; 
     printf("\t\t%d\n", ++variable); 
    } 
    printf("Thread1: Sleeping\n"); 
    pthread_mutex_unlock(&lock); 
    usleep(1000); 
} 
RETURN: 
pthread_mutex_unlock(&lock); 
return NULL; 
} 

void *thread2(void *arg) 
{ 
while (1) { 
    pthread_mutex_lock(&lock); 
    printf("Thread2: \n"); 
    int i; 
    for (i=0; i<ONE_TIME_INC; i++) { 
     if (variable >= MAX) 
      goto RETURN; 
     printf("%d\n", ++variable); 
    } 
    printf("Thread2: Sleeping\n"); 
    pthread_mutex_unlock(&lock); 
    usleep(1000); 
} 
RETURN: 
pthread_mutex_unlock(&lock); 
return NULL; 

} 

int main() 
{ 

if (pthread_mutex_init(&lock, NULL) != 0) { 
    printf("\n mutex init failed\n"); 
    return 1; 
} 

pthread_t pthread1, pthread2; 
if (pthread_create(&pthread1, NULL, thread1, NULL)) 
    return -1; 
if (pthread_create(&pthread2, NULL, thread2, NULL)) 
    return -1; 

pthread_join(pthread1, NULL); 
pthread_join(pthread2, NULL); 

pthread_mutex_destroy(&lock); 

return 0; 
} 
1

1:最も簡単な方法は、ミューテックスを使用することです。 この

int counter=1; 
pthread_mutex_t mutex; //needs to be initialised 

void incrementGlobal() { 
    for(int i=0;i<5;i++){ 
     counter++; 
     printf("%i\n",counter); 
    } 
} 

T1/T2不当/未定義shedulingの基本的な実装である:

pthread_mutex_lock(&mutex); 
incrementGlobal(); 
pthread_mutex_unlock(&mutex); 

2: (これは、よりグローバル必要が正しい順序は、条件付き変数をarchievedすることができます - 変数)

グローバル:

int num_thread=2; 
int current_thread_id=0; 
pthread_cond_t cond; //needs to be initialised 

T1/T2:

int local_thread_id; // the ID of the thread 
while(true) { 
    phread_mutex_lock(&mutex); 
    while (current_thread_id != local_thread_id) { 
     pthread_cond_wait(&cond, &mutex); 
    } 
    incrementGlobal(); 
    current_thread_id = (current_thread_id+1) % num_threads; 
    pthread_cond_broadcast(&cond); 
    pthread_mutex_unlock(&mutex); 
} 
関連する問題