2015-11-02 90 views
0

我有2個線程:將重新打印用戶輸入語句的元音和輔音。元音線程將打印以元音開頭的單詞,輔音線程將打印以輔音開頭的單詞...我試圖用sched_yield()以與用戶輸入相同的順序輸出... 因此,如果用戶輸入是:大家好,輔音線程將打印嗨和元音將打印所有,按順序..但它似乎我缺少的東西,因爲我沒有得到相同的順序..你能幫助...使用sched_yield來控制線程執行

void *vowels(void *s) 
{ 
    for(int i = 1; i < noOfTokens; i++){ 
     string str = tokens[i]; 
     size_t found = str.find_first_of(vowelList); 
     if(found == 0){ 
      printf("vows %s\n", tokens[i]); 
     } 
     else { 
      sched_yield(); 
     } 
    } 
    pthread_exit(0); 
} 


/* the cons thread should print all words starting with a consonant. */ 
void *consonants(void *s) 
{ 
    for(int j = 1; j < noOfTokens; j++){ 
     string str = tokens[j]; 
     size_t found = str.find_first_of(vowelList); 
     if(found != 0){ 
      printf("cons %s\n", tokens[j]); 
     } 
     else { 
      sched_yield(); 
     } 
    } 
    pthread_exit(0); 

} 
+2

沒有一些線程間通信,這將無法工作。 'yield'是調度員的一個信息,基本上說:「我現在不需要更多的時間來運行,請繼續,給我喜歡的任何線程,包括我」。看看使用信號量或互斥量。 – Kenney

+0

除非有更多可直接運行的線程比內核多,否則你的線程沒有任何優勢,所以'sched_yield'不會做任何事情。 –

回答

1

正如肯尼所說,單獨使用yield不會幫助您同步這兩個線程。爲此,您必須使用互斥鎖或其他同步原語。話雖如此,我忍不住注意到你的問題可以在condition variable的幫助下得到優雅的解決。我選擇使用c++11std::thread,以及std::mutexstd::condition_variable

我簡化了一下你的問題,我的目標是打印偶數和奇數整數按照它們輸入的順序購買兩個不同的線程(一個線程負責偶數,另一個線程負責奇數)。一個可能的解決方案可能是:

#include <iostream> 
#include <vector> 
#include <thread> 
#include <mutex> 
#include <condition_variable> 

std::mutex m; 
std::condition_variable cv; 
unsigned int index = 0; 

void ProcessEvenNumbers(void *p_array) 
{ 
    std::vector<int>& buffer(*reinterpret_cast<std::vector<int>*>(p_array)); 
    std::unique_lock<std::mutex> lock(m); 

    while (index < buffer.size()) 
    { 
     if (buffer[index] % 2 == 0) 
     { 
      std::cout << "thread_1: " << buffer[index] << std::endl; 
      ++index; 
     } 
     else 
     { 
      cv.wait(lock); 
     } 
    } 
} 

void ProcessOddNumbers(void *p_array) 
{ 
    std::vector<int>& buffer(*reinterpret_cast<std::vector<int>*>(p_array)); 
    std::unique_lock<std::mutex> lock(m); 

    while(index < buffer.size()) 
    { 
     if (buffer[index] % 2 != 0) 
     { 
      std::cout << "thread_2: " << buffer[index] << std::endl; 
      ++index; 
     } 
     else 
     { 
      lock.unlock(); 
      cv.notify_one(); 
      std::this_thread::sleep_for(std::chrono::microseconds(1)); 
      lock.lock(); 
     } 
    } 

    cv.notify_one(); 
} 

int main() 
{ 
    std::vector<int> buffer{ 1, 3, 24, 5, 100, -23, -2, -2, 7, 9, 11, 13, 15, 17, 2, 4, 6, 8, 10, 12, 14 }; 
    std::thread thread_2(ProcessOddNumbers, &buffer); 
    std::thread thread_1(ProcessEvenNumbers, &buffer); 

    thread_1.join(); 
    thread_2.join(); 

    return 0; 
} 

,處理偶數線程(ProcessEvenNumbers())使用條件變量,當它遇到奇數到框本身。處理奇數的線程(ProcessOddNumbers())使用notify_one()在遇到偶數時解鎖其他線程,並通過嘗試重新鎖定互斥體(即此時已被其他線程鎖定)來阻止自己。

std::this_thread::sleep_for()是至關重要的,因爲它強制上下文切換,允許thread_1thread_2發信號通知條件變量後鎖定互斥鎖。

P.S.線程運行的順序是不相關的。