【问题标题】:Semaphore lock is not working properly in Problem信号量锁在问题中无法正常工作
【发布时间】:2019-04-02 11:57:35
【问题描述】:

我有评估问题:

服务器可以设计成限制打开的数量 连接。例如,服务器可能希望在任何时候只有 N 个套接字连接 及时。一旦建立了 N 个连接,服务器将不会接受另一个传入的 连接,直到现有连接被释放。使用信号量编写程序 同步服务器活动以限制并发连接数。

为了解决这个问题,我创建了 2 个信号量:

  1. 初始化为 N 的信号量。
  2. 提供互斥的信号量。

我必须以这样一种方式创建,如果所有 N 连接都建立,客户端必须等到释放。

我已尝试对其进行编码,但代码无法正常工作:

 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>
 #include<pthread.h>
 #include<semaphore.h>
 #include<stdlib.h> 
 #include<string.h>

sem_t allow;
sem_t mutex;

void *acquire(void * arg)
{
 int tid = *(int *)arg;
 tid+=1;
 sem_wait(&mutex);

 sem_wait(&allow);                       


printf("\n Client %d is connected to the server....",tid);
sem_post(&mutex);
sleep(rand()%10);
release(tid);

}
void  release(int num)
{
  printf("\n Client %d releases the Server ....",num);
  sem_post(&allow);                       
}   
void main(int argc,char ** argv)
{
int n;
int i;
printf("\n Enter the number of client :");
scanf("%d", &n);
int maxi=3;         // maximum no. of connection available
sem_init(&allow,0,maxi);  // semaphore that is initialised to maxi. 
                           //no. of connection
sem_init(&mutex,0,1);  // for mutual exclusion

pthread_t thread[n];

for(i=0;i<n;i++) {
    pthread_create(&thread[i],NULL,acquire,&(i));   // Clients are 
                                                  // acquiring ..
}

for(i=0;i<n;i++)
    pthread_join(thread[i],NULL);

sem_destroy(&allow);
sem_destroy(&mutex);

}

它给出不同的执行顺序,甚至在获取连接(客户端“x”)之前它释放连接,就像..

输出:

输入客户数量:6

客户端 3 连接到服务器....

客户端 3 连接到服务器....

客户端 4 连接到服务器....

客户端 3 释放服务器 ....

客户端 6 连接到服务器....

客户端 3 释放服务器 ....

客户端 6 连接到服务器....

客户端 4 释放服务器 ....

客户端 1 连接到服务器....

客户端 6 释放服务器 ....

客户端 6 释放服务器 ....

客户端 1 释放服务器 ....

请帮我更正代码!!

抱歉标题不好!!!

【问题讨论】:

    标签: c multithreading operating-system posix semaphore


    【解决方案1】:

    最可能的问题是您如何创建线程:

    pthread_create(&thread[i],NULL,acquire,&(i));
    

    作为线程的参数,您传递一个指向局部变量i 的指针。问题是所有线程获取相同的指针,这可能意味着多个线程可以取消引用它并获取相同的值!

    通常不应该将普通值转换为指针,但在这种情况下,它通常被接受。但是,您不应该直接转换为指针,而是使用 standard fixed width type intptr_t 然后将其转换为指针:

    pthread_create(&thread[i],NULL,acquire,(void *) (intptr_t) i);
    

    然后你在线程函数中做相反的转换:

    void *acquire(void * arg)
    {
        int tid = (int) (intptr_t) arg;
        ...
    }
    

    这样每个线程都会有自己的“id”。

    【讨论】:

      猜你喜欢
      • 2017-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      相关资源
      最近更新 更多