使用信号量的制作人/消费者

时间:2016-05-28 02:17:16

标签: c linux semaphore

我使用semaphore开始同步线程的学习 我刚刚使用二进制信号量进行了测试(仅限2个线程)并且它都很好。

想象一个拥有3台计算机(线程)和一些客户端(线程)的局域网。如果所有计算机都处于忙碌状态,则客户端将在具有已知限制的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;
}

2 个答案:

答案 0 :(得分:1)

如果你是技术人员,如果你在线程之间同步任务,你应该使用信号量。在解析输入之前读取输入的示例。 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不确定你正在运行的是什么)

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

答案 1 :(得分:1)

您可以将计算机视为资源。资源的数据结构可以由主线程初始化。然后,可能有客户端线程试图获取资源实例(计算机)。您可以使用值为3的计数信号量作为计算机数量。要获取计算机,客户端线程

P (computer_sem).

与发布客户端线程类似,

V (computer_sem)

有关线程和信号量使用的更多信息,请参阅 POSIX Threads Synchronization in C