信号灯锁定在问题中无法正常工作

时间:2018-10-29 14:15:42

标签: c multithreading operating-system posix semaphore

我的配偶问题指出:

可以设计服务器以限制打开次数 连接。例如,服务器可能希望在任何时候只有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释放服务器....

请帮助我更正代码!

对不起,标题不好!

1 个答案:

答案 0 :(得分: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”。