2016-12-23 12 views
1

私はゲートウェイサーバーと2つのクライアントを持っています(Oracle VM VirtualBoxで作成)。スレッド内のsleep()がメインをスリープさせます

私のゲートウェイサーバーでは、すべてのパケットをlistenするlistener.cがあります(while(1)ループ内)。

クライアントが有効なトークンを送信する場合は、許可されたMACリストに入れなければなりません。許可されたMACからのすべてのパケットは180秒間転送する必要があります。 (換言すれば、180秒間のインターネットアクセスが可能)。

前に180秒、それは単一のユーザーとのものは働いていた。

/* authorized MACs list */ 
char *auth_macs[5]; 
int client; 
pthread_mutex_t lock; 

/* after 3 min remove the client from auth list */ 
void *timer(void *arg){ 
    sleep(180); 
    pthread_mutex_lock(&lock); 
    auth_macs[client] = " "; 
    client--; 
    pthread_mutex_unlock(&lock); 
    return NULL; 
} 

これは私がタイマースレッドを実装しようとした方法です。 clientは、メイン関数で変更されるグローバル変数です。

if(has_token == 1){ 
    client++; 
    sprintf(client_ip, "./accept.sh %s", sender); 
    system(client_ip); 
    auth_macs[client] = client_mac; 
    /* start timer thread */ 
    pthread_t tid; 
    pthread_create(&tid, NULL, timer,NULL); 
    pthread_join(tid, NULL); 
} 

ここで私はこのスレッドを開始します。 accept.shは、転送を許可するシェルスクリプトです。

私の問題はです。タイマースレッドのsleep(180)はそれ自体停止するつもりだと思いました。代わりに、listener.cはパケットの受信を停止します。

どうすればこの問題を解決できますか?私はタイマーが180秒待つが、メイン機能でパケットを受信できるようにしたい。

+4

'pthread_join'は、スレッドが終了するのを待ちます。しかし、それは長い間眠ります。 –

答えて

2

sleep()は、呼び出し元のスレッドのみを一時停止します。したがって、メインスレッドには影響しません。これが効果的に無意味なマルチスレッドをレンダリングする

pthread_create(&tid, NULL, timer,NULL); 
pthread_join(tid, NULL); 

:問題は何

pthread_join()呼び出しです。なぜなら、メインスレッドが作成されたスレッドが完了するまで待機するので、進歩するスレッドしかないからです。

あなたは、メインスレッドが参加するために必要であれば、おそらくpthread_join()呼び出し、それwhile(1)ループを削除する必要があります。または、スレッド作成ループの外側にpthread_exit(0)を呼び出して、メインが実行を完了し、残りのスレッドがメインスレッド がループを解除してもまだ実行されている場合は実行を継続できます。

+1

また、通常のスレッドではなくデーモンスレッドを使用して、参加する必要はありません。 –

+1

@JohnBollingerこのテクニックの問題は、メインスレッドが終了すると、デーモンスレッドがまだ使用しているリソースを解放し、デーモンスレッドで未定義の動作を引き起こす可能性が高いことです。順序の整ったシャットダウンシーケンスを整える方が良いでしょう。 –

関連する問題