2015-10-15 90 views
1

我正在實現一個點對點和跟蹤器的P2P文件傳輸。跟蹤器跟蹤所有對等端及其文件,並且當想要下載文件時對等端連接到另一個對等端,並且接受來自其他對等端的下載其文件之一的請求。爲此,我的同事既充當客戶和服務器,又充當其他同行,同時也是追蹤者的客戶。爲此,我使用線程,並在一個線程中使用服務器進程,在另一個線程中使用客戶端進程,並在主線程中使用連接到跟蹤器的進程。當對等體選擇退出時,我想關閉它的服務器進程,也就是:單獨服務器線程中的進程。我嘗試了一個包含文件描述符的全局變量,然後當客戶端退出時我可以關閉它,但是在退出後這給我一個錯誤。從主線程關閉一個套接字

這裏是我的同行代碼:

+1

什麼是錯誤? –

回答

0

如果你想知道如何從主線程阻止其他線程這裏是一個方法。我會創建一個結構,我們稱它爲thread_state_t,它有一個標誌,告訴你的線程停止,例如稱之爲active。在線程中,您可以在循環中檢查其值,並根據狀態執行所需的任何操作。

在簡單的情況下,它看起來像這樣

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

typedef struct { 
    int active; 
} thread_state_t; 

void* t1(void* arg) { 
    thread_state_t* state = (thread_state_t*) arg; 
    while(state->active > 0) { 
     // do work 
    } 
    return NULL; 
} 

int main() { 
    pthread_t tid; 
    thread_state_t state1; 
    state1.active = 1; 

    pthread_create(&tid, NULL, t1, (void*)&state1); 

    // ... 
    state1.active = 0; 
    // ... 

    pthread_join(tid, NULL); 

    return 0; 
} 

但是這個例子只是向你展示的主要理念。在實際實現中,您需要使對象線程安全(例如,使用mutex)使可變或完整的active變量或整個thread_state_t對象線程安全。

爲了讓線程安全的,您可以使用添加互斥狀態對象

typedef struct { 
    pthread_mutex_t mutex; 
    int active; 
} thread_state_t; 

,並添加一些功能,如從state->active > 0get_active(state) > 0這些

void init_state(thread_state_t* state) { 
    state->active = 1; 
    pthread_mutex_init(&state->mutex, NULL); 
} 

void remove_state(thread_state_t* state) { 
    state->active = 0; 
    pthread_mutex_destroy(&state->mutex); 
} 

int get_active(thread_state_t* state) { 
    int active = 0; 
    pthread_mutex_lock(&state->mutex); 
    active = state->active; 
    pthread_mutex_unlock(&state->mutex); 
    return active; 
} 

void set_active(thread_state_t* state, int active) { 
    pthread_mutex_lock(&state->mutex); 
    state->active = active; 
    pthread_mutex_unlock(&state->mutex); 
} 

然後改變循環條件,並在主代碼線程看起來像這樣(sleep這裏只是舉例)

int main() { 
    pthread_t tid; 
    thread_state_t state; 
    init_state(&state); 

    pthread_create(&tid, NULL, t1, (void*)&state); 

    sleep(1); 
    set_active(&state, 0); 

    pthread_join(tid, NULL); 
    remove_state(&state); 

    return 0; 
} 

另一種使用pthread_cancel的方式。然而,這不是最好的解決方案。