2016-05-28 72 views
1

我開始使用semaphore與syncronzed線程進行學習。
我只是做了一個測試使用二進制信號量(僅2線程),它都很好。使用信號量的生產者/消費者

想象一下lanhouse,它有3臺計算機(線程)和一些客戶端(線程)。如果所有計算機都是bussy,那麼客戶端將在具有知識限制的queue(例如15個客戶端)中等待。

我不明白線程將如何相互關聯。

據我所知,semaphore用於控制線程訪問某個關鍵區域/內存區域/全局變量。

1)創建1個信號燈來控制訪問計算機的客戶端(但都是線程);

2)創建1個信號來控制queue中的客戶端;

但是如何將線程與線程相關聯?信號量如何知道它應該使用哪個線程。

我不需要一個完整的答案。我只需要了解Threads與彼此的關係。一些有助於瞭解情況。

這是我的代碼到目前爲止,它不工作; P無法控制客戶端訪問3臺計算機可用。

#include <pthread.h> 
#include <semaphore.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#define ROOM_SIZE 15 

sem_t queue, pc, mutex; 
int room [ROOM_SIZE]; 
int pcsAvaliable = 3, nAvaliable = 0, roomAvaliable = ROOM_SIZE; 
int computers [3]; // 0 -> Empty | 1 -> Ocuppied 

void* Lan(void* arg) 
{ 
    //Enter the lanhouse 
    //Verify if there is a computer avaliable 
    sem_wait(&pc); 

    if(pcsAvaliable > 0) 
    { 
     sem_wait(&mutex); 
     pcsAvaliable--; 
     computers[nAvaliable] = 1;  
     printf("Cliente pegou pc: %d\n", nAvaliable); 
     nAvaliable++; 
     sem_post(&mutex); 

     //Wait for 80~90ms 
     printf("Client liberou pc: %d\n", nAvaliable); 
     computers[nAvaliable] = 0; 
     nAvaliable--; 

     sem_post(&pc); 
    } 
    else 
    { 
     printf("No computer avaliable...\n"); 
     //Check the waiting room for avaliable slot 
     if(roomAvaliable > 0) 
     { 
      roomAvaliable--; 
      printf("Client entered the waiting room."); 
     } 
     else 
      printf("No avaliable space in waiting room..\n"); 
    } 



} 

int main(int argc, char const *argv[]) 
{ 
    int i; 

    if(argc > 1) 
    { 
     int numClients = atoi(argv[1]); 
     sem_init(&pc, 0, 3); 
     sem_init(&mutex, 0, 1); 
     pthread_t clients[numClients]; 

     //Create Clients 
     for(i=0; i< numClients; i++) 
     { 
      pthread_create(&clients[i], NULL, Lan, NULL); 
     } 

     //Join Clients 
     for(i=0; i< numClients; i++) 
     { 
      pthread_join(clients[i], NULL); 
     } 

    } 
    else 
     printf("Please, insert a parameter."); 
    pthread_exit(NULL); 
    sem_destroy(&pc); 
    return 0; 
} 

回答

1

如果你打算技術性的話,如果你在線程之間同步任務,你應該使用Semaphore。在解析它之前閱讀輸入示例。 Here's關於信號量的答案。

但是,如果您使用的是共享資源,並且需要避免競態條件/兩個線程同時訪問,則應該使用互斥鎖。 Here's關於什麼是互斥量的問題。

也看看邁克爾巴爾disambiguation這是一個很好的。

我會仔細閱讀這兩個問題和消歧,你可能最終不會使用信號量和互斥量,因爲從你解釋你只控制共享資源。

常見信號功能

int sem_init(sem_t *sem, int pshared, unsigned int value); //Use pshared with 0, starts the semaphore with a given value 

int sem_wait(sem_t *sem);//decreases the value of a semaphore, if it's in 0 it waits until it's increased 

int sem_post(sem_t *sem);//increases the semaphore by 1 

int sem_getvalue(sem_t *sem, int *valp);// returns in valp the value of the semaphore the returned int is error control 

int sem_destroy(sem_t *sem);//destroys a semaphore created with sim_init 

通用互斥功能(對於Linux不知道O.S.你在運行什麼)

int pthread_mutex_init(pthread_mutex_t *p_mutex, const pthread_mutexattr_t *attr); //starts mutex pointed by p_mutex, use attr NULL for simple use 

int pthread_mutex_lock(pthread_mutex_t *p_mutex); //locks the mutex 

int pthread_mutex_unlock(pthread_mutex_t *p_mutex); //unlocks the mutex 

int pthread_mutex_destroy(pthread_mutex_t *p_mutex);//destroys the mutex 
+0

在這兩種情況下將使用常用函數發佈編輯 –

+0

我正在閱讀您發佈的主題的一些答案,我想我應該使用信號量......無論如何,我都不知道如何控制'客戶端','電腦「和」隊列「。有小費嗎 ? – PlayHardGoPro

+1

我想爲隊列使用一個隊列數據結構(這會稍微複雜一些),或者可能是一個循環緩衝區。如果您知道客戶端的最大數量一直在緩衝區中使用。當您接收到客戶端時,將它們放入隊列/緩衝區中,當計算機釋放時,將下一個客戶端分配給計算機。如果您在客戶端離開sem_post時使用信號量,並且有一個處理程序檢查每臺計算機的信號值,只要一個> 0,您就爲其分配一個客戶端。如果你發佈一些代碼,我可以幫助更多。我只是給出想法,以便你可以嘗試開始。 –

1

你可以把電腦作爲資源。該資源的數據結構可以由主線程初始化。然後,可能有客戶端線程試圖獲取資源(計算機)的實例。您可以使用值爲3的計數信號量作爲計算機的數量。爲了獲得一臺電腦,一個客戶端線程做

P (computer_sem). 

同樣以釋放客戶端線程都有做,

V (computer_sem) 

有關線程和信號燈使用的更多信息,請參閱 POSIX Threads Synchronization in C

+0

但資源(電腦)可以是任何東西?像3位和0或1(bussy或avaliable)的矢量? 無法理解我將如何「告訴」哪臺計算機已被哪個客戶端使用。 – PlayHardGoPro

+0

如果使用計數信號量,則假定資源是相同的。如果資源不同,請爲每個資源使用一個信號量。 – kjohri

+0

有呀!你能看看我的代碼,請...只是一些指導。有時他們只使用PC 0,有時他們使用0和1,但在輸入之前他們保留1。它的一個混亂 – PlayHardGoPro