2013-06-19 19 views
1

我認爲我面臨着種族問題,但不確定。 以下是我的代碼。它如何成爲競賽條件。或者我的代碼有問題

while(1) 
{ 
    int newsocket_fd; = accept(socket_fd,(struct sockaddr *) &client_addr, &client_len); 

    if (newsocket_fd < 0) 
    { 
      perror("Error on accept"); 
    } 
    else 
    { 
     pthread_create(&threadNewClient, NULL, NewClient, (void *)&newsocket_fd); 
    } 
} 

我發送int variable(newsocket_fd)的地址作爲線程參數。

void* NewClient(void * thread_args) 
{ 
    int client_socket = *(int*)thread_args; 
    char buffer[256]; 
    int n; 
    stringstream userInput,responseString; 

    printf(KBLU "Client conneted %d\n",client_socket); 
} 

這裏我正在接收線程參數和類型轉換它。當我打印(或使用)它的值時,它大部分時間都給出了發送到前一個線程的值(相同的線程函數)。我在網上搜索,有人認爲這是由於競爭條件。

當我發送值而不是地址作爲參數時,它工作正常。我訪問具有不同值的同一個地址,它怎麼會成爲競爭條件。

在此先感謝。

@Edit:created int newsocket_fd;在while循環中。

回答

7

因爲您發送的是堆棧位置整數的地址(newsocket_fd)。這將被重用,然後下一次套接字被接受。發送整數值有什麼問題?

+0

請看我編輯過的帖子吧。在這裏我重新創建int newsocket_fd,它仍然是競爭狀態? – user2481987

+0

發送整數值有什麼問題?答。現在我只發送int值。技術上正確。但從概念上講,這是錯誤的,不是嗎? – user2481987

+0

如果你這樣做,那麼只要你循環,'newsocket_fd'就會超出範圍,所以不再有一個有效的地址。如果你的線程啓動得足夠快,那麼它會很好,否則你會訪問一個無效的指針。 (實際上編譯器在兩種情況下可能都會做同樣的事情) – Nick

3

newsocket_fd可能會在新線程從您指定的指針讀取它之前修改(或更糟糕的是,銷燬並重新創建)。這絕對是一個競賽條件。

最簡單的修復方法就是不在線程之間共享相同的變量。如果您絕對必須出於某種原因或其他原因執行此操作,那麼您必須確保在線程完成讀取操作之前,使用某個同步對象(條件),不會修改它。

+0

請看我現在編輯的文章。在這裏我重新創建int newsocket_fd,它仍然是競爭狀態? – user2481987

+0

是的,現在只有更差的一個,因爲線程可能訪問堆棧變量,爲什麼它不再存在。我也編輯了我的帖子。 – Medinoc

+1

只有一個答案可以被標記爲接受。否則這也滿足了我的要求。 – user2481987