C 使用信号量的生产者/消费者

C 使用信号量的生产者/消费者,c,linux,semaphore,C,Linux,Semaphore,我正在使用信号量 我刚刚用二进制信号量做了一个测试(仅2个线程),一切正常 想象一个lanhouse,它有3台计算机(线程)和一些客户端(线程)。如果所有计算机都处于总线状态,则客户端将在一个已知限制的队列中等待(例如15个客户端) 我无法理解线程之间的关系 据我所知,信号量用于控制线程对某个关键区域/内存区域/全局变量的访问 1) 创建1个信号量来控制访问计算机的客户端(但两者都是线程) 2) 创建1个信号量来控制队列中的客户端 但是线程与线程之间如何关联呢?信号量如何知道应该使用哪个线程 我

我正在使用
信号量

我刚刚用二进制信号量做了一个测试(仅2个线程),一切正常

想象一个lanhouse,它有3台计算机(线程)和一些客户端(线程)。如果所有计算机都处于总线状态,则客户端将在一个已知限制的
队列中等待(例如15个客户端)

我无法理解线程之间的关系

据我所知,
信号量
用于控制线程对某个关键区域/内存区域/全局变量的访问

1) 创建1个信号量来控制访问计算机的客户端(但两者都是线程)

2) 创建1个信号量来控制
队列中的客户端

但是线程与线程之间如何关联呢?信号量如何知道应该使用哪个线程

我不需要一个完整的答案。我只需要了解
线程之间的关系。有些有助于了解情况

到目前为止,这是我的代码,它不起作用;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;
}
#包括
#包括
#包括
#包括
#包括
#定义房间大小15
扫描队列、pc、互斥体;
内部房间[房间大小];
int pcsAvaliable=3,nAvaliable=0,RoomAvailable=房间大小;
int计算机[3];//0->空| 1->已应用
void*Lan(void*arg)
{
//进屋
//验证是否有可用的计算机
sem_wait(和pc);
如果(pcsAvailable>0)
{
sem_等待(&mutex);
PCsAvailable--;
计算机[导航]=1;
printf(“客户pegou pc:%d\n”,可导航);
导航++;
sem_post(和互斥);
//等待80~90毫秒
printf(“客户端自由pc:%d\n”,可导航);
计算机[可导航]=0;
导航--;
sem_post(和pc);
}
其他的
{
printf(“没有可用的计算机…\n”);
//检查候机室是否有可用的插槽
如果(RoomAvailable>0)
{
可提供房间--;
printf(“客户进入等候室”);
}
其他的
printf(“候诊室没有可用空间..\n”);
}
}
int main(int argc,char const*argv[]
{
int i;
如果(argc>1)
{
int numClients=atoi(argv[1]);
sem_init(&pc,0,3);
sem_init(&mutex,0,1);
pthread_t客户端[numClients];
//创建客户机
对于(i=0;i
如果你想成为一名技术人员,如果你要在线程之间同步任务,你应该使用信号量。解析输入之前读取输入的示例。 关于信号量的回答

但是如果您使用的是共享资源,并且需要避免竞争条件/两个线程同时访问,那么应该使用互斥锁。关于什么是互斥的问题

再看看迈克尔·巴尔的作品,这是一部非常好的作品

我会仔细阅读问题和歧义消除,最终可能不会使用信号量,而只使用互斥,因为根据您的解释,您只控制一个共享资源

公共信号量函数

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.)


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

P (computer_sem).
与发布类似,客户端线程必须执行以下操作:

V (computer_sem)
有关线程和信号量使用的更多信息,请参阅
.

将在两种情况下使用常用函数进行后期编辑我正在阅读您发布的主题的一些答案,我想我还是应该使用信号量。。。只是不知道如何控制“客户端”、“计算机”和“队列”。有什么建议吗?我会为队列使用队列数据结构(这会稍微复杂一点),或者使用循环缓冲区。如果您知道客户端的最大数量,则会一直使用缓冲区。当您接收客户端时,您将它们放入队列/缓冲区,当计算机释放时,您将下一个客户端分配给该计算机。如果您在客户端离开sem_post时使用信号量,并让处理程序检查每台计算机的信号量值,则只要一台大于0,您就为其分配一个客户端。如果你发布一些代码,我可以提供更多帮助。我只是给你一些想法,让你可以试着开始。但是资源(计算机)可以是任何东西吗?类似于有3个位置和0或1的向量(bussy或available)?无法理解如何“告诉”哪台计算机被哪台客户端使用。如果使用计数信号量,则假定资源相同。如果资源不同,则为每个资源使用一个信号量。明白了!你能看一下我的密码吗。。。只是一些指导。有时他们只使用PC 0,有时他们使用0和1,但在输入前先离开1。梅西建议,一个好的方法是使用一个工作示例和模型代码。
V (computer_sem)