2017-02-16 13 views
0

我正在嘗試創建一個程序來創建多個進程,每個進程從控制檯讀取一行,然後執行其中的操作。我僅在有時閱讀一條線時遇到了getline(cin, temp)的問題。輸入緩衝區已經加載了4行文本。C++ Getline並不總是在Linux中的多分叉進程中行

編輯:我需要使用fork,它創建多個進程(而不是線程),以便使用wait,它等待第一個子進程完成,然後繼續。

#include <iostream> 
#include <iostream> 
#include <string> 
#include <cstring> 
#include <sstream> 
#include <unistd.h> 
#include <sys/wait.h> 

using namespace std; 

int childprog(); 

int main() 
{ 

    pid_t childpid; 

    for (int i = 0; i < 4; ++i) 
    { 
     if ((childpid = fork()) == 0) //Child process 
     { 
      childprog(); 
      return 0; 
     } 
    } 

    if (childpid != 0) //If Parent 
    { 
     wait(0); 
     //Stuff 
     return 0; 
    } 
} 

int childprog() 
{ 
    string temp; 
    getline(cin, temp); 
    cout << temp << endl; //Actually do other stuff, just here for debugging 
    return 0; 
} 

雖然它應該打印出來:

string number one 
string number two 
string number three 
string number four 

它打印出:

string number one 

string number two 
string number three 

(blank line) 
string number one 

string number two 

在任何可能的位置的空行。

感謝您的幫助!

+0

你可以提供[MCVE]嗎? –

+0

好的,完成了。該程序是完全可運行的@πάνταῥεῖ – DDriggs00

回答

0

@JasonLang發佈了他的回答,告訴我這是一個訪問問題,我找到了一個解決方案。我通過簡單地將輸入緩衝區的讀數移動到fork()之前來糾正它,確保只有一個進程會嘗試一次讀取它。

我換成這樣的:

for (int i = 0; i < 4; ++i) 
{ 
    if ((childpid = fork()) == 0) //Child process 
    { 
     childprog(); 
     return 0; 
    } 
} 

與此:

string temp; 
for (int i = 0; i < 4; ++i) 
{ 
    getline(cin, temp); 
    if ((childpid = fork()) == 0) //Child process 
    { 
     childprog(temp); 
     return 0; 
    } 
} 

這:

int childprog() 
{ 
    string temp; 
    getline(cin, temp); 
    cout << temp << endl; //Actually do other stuff, just here for debugging 
    return 0; 
} 

與此:

int childprog(string input) 
{ 
    cout << input << endl; //Actually do other stuff, just here for debugging 
    return 0; 
} 
0

問題是每個線程正在訪問共享資源:getline和輸入緩衝區。有些操作是原子操作,其他操作可能會中斷。

這意味着操作的確切時間可能會相互干擾。例如,兩個線程檢查讀取哪一行,它們都被告知相同的行。然後,這是一個「競爭條件」,看看哪些人先讀取它,另一個線程獲得空行。

您需要以某種方式鎖定getline,以便每個線程在其他人潛入之前可以讀取一行,然後嘗試並獲取一些數據。一個更好的解決方案是避免兩個進程處理相同的數據,但假設你不能,那麼你可以使用Mutex。

http://www.thegeekstuff.com/2012/05/c-mutex-examples/

一個剝離下來的實例的互斥體的使用方式:

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

pthread_mutex_t lock; 

int childprog() 
{ 
    // Put the mutex lock and unlock around the minimum amount of code  
    // which needs to be an "atomic operation". While "locked" other 
    // threads won't run this bit of code, so keep it brief. However, 
    // Locking and unlocking is itself an expensive operation, so you 
    // should be careful to minimize the number of times it happens 

    string temp; 

    pthread_mutex_lock(&lock); 
    getline(cin, temp); 
    pthread_mutex_unlock(&lock); 

    cout << temp << endl; 

    return 0; 
} 

// the rest of your program here 

但是請注意,也有一個線需要你用它

pthread_mutex_init(&lock, NULL) 

之前初始化互斥而鏈接的例子是使用pthread創建,而不是fork

+0

我需要使用'wait',它不能與線程一起工作,只能使用單獨的進程。互斥體僅適用於線程,因爲進程在單獨的內存空間中運行。 – DDriggs00