繁体   English   中英

意外的pthread函数输出

[英]Unexpected pthread function output

我是C语言的新手,正在学习信号量。 我正在尝试使用pthreads,mutex和semaphores实现某种复杂的餐饮哲学家的情况。

这个想法是,一个代表服务器的信号灯可将人们坐在两张桌子上(每张桌子有4个席位,共8个席位)。 每个表还由计数信号量控制。 每个板块均由互斥锁控制,以免出现竞争状况。 每个人都由一个线程代表。

我看不出为什么在我的代码中,同一位客户不断进餐,而且似乎没有增加。

码:

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


sem_t server_sem;
int server_pshared;
int server_ret;
int server_count = 10;

sem_t tablea_sem;
int tablea_pshared;
int tablea_ret;
int tablea_count = 4;

sem_t tableb_sem;
int tableb_pshared;
int tableb_ret;
int tableb_count = 4;



//server_ret = serm_open("serverSem", O_CREAT | O_EXCL, 0644, server_count);

int customer_count = 10;
pthread_t customer[10];
//pthread_t plates[8]

int plate_count = 8;
pthread_mutex_t plates[8];


void *eat(void *i) {

    int n = *((int *) i);

    pthread_mutex_lock(&plates[n]);
    printf("Customer %d is eating\n", n);
    sleep(5);
    pthread_mutex_unlock(&plates[n]);
    printf("Customer %d is finished eating\n", n);

    return (NULL);
}

int main() {


   server_ret = sem_init(&server_sem, 1, server_count);
   tablea_ret = sem_init(&tablea_sem, 1, tablea_count);
   tableb_ret = sem_init(&tableb_sem, 1, tableb_count);

   //customer = (pthread_t[10] *)malloc(sizeof(customer));

   printf ("starting thread, semaphore is unlocked.\n");

   int i;
   int j;
   int k;




   for(i=0;i<plate_count;i++) {
      pthread_mutex_init(&plates[i],NULL);
      printf("Creating mutex for plate %d\n", i);
   }

   sem_wait(&server_sem);

   for (j=0;j<customer_count;j++) {
      //pthread_create(&customer[j],NULL,(void *)eat,&j);
      if (j<4) {
        sem_wait(&tablea_sem);
        sem_post(&tableb_sem);
        pthread_create(&customer[j],NULL,(void *)eat,&j);

        printf("Creating thread for customer %d\n", j);
      }
      else {
        sem_post(&tablea_sem);
        sem_wait(&tableb_sem);
        pthread_create(&customer[j],NULL,(void *)eat,&j);

        printf("Creating thread for customer %d\n", j);
      }

   }

   for(k=0;k<customer_count;k++) {
      pthread_join(customer[k],NULL);
      printf("Joining thread %d\n", k);
   }

   for(i=0;i<plate_count;i++) {
      pthread_mutex_destroy(&plates[i]);
   }

   return 0;
   }

控制台输出:

starting thread, semaphore is unlocked.
Creating mutex for plate 0
Creating mutex for plate 1
Creating mutex for plate 2
Creating mutex for plate 3
Creating mutex for plate 4
Creating mutex for plate 5
Creating mutex for plate 6
Creating mutex for plate 7
Creating thread for customer 0
Creating thread for customer 1
Creating thread for customer 2
Creating thread for customer 3
Creating thread for customer 4
Creating thread for customer 5
Creating thread for customer 6
Creating thread for customer 7
Creating thread for customer 8
Creating thread for customer 9
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Customer 10 is finished eating
Joining thread 0
Joining thread 1
Joining thread 2
Joining thread 3
Joining thread 4
Joining thread 5
Joining thread 6
Joining thread 7
Joining thread 8
Joining thread 9

编辑:

更新pthread_create的最后一个参数解决了客户增加的问题:

pthread_create(&customer[j],NULL,(void *)eat,(void *) (intptr_t) j);

但是,它从6开始,然后是索引超出范围的问题。

现在控制台输出:

starting thread, semaphore is unlocked.
Creating mutex for plate 0
Creating mutex for plate 1
Creating mutex for plate 2
Creating mutex for plate 3
Creating mutex for plate 4
Creating mutex for plate 5
Creating mutex for plate 6
Creating mutex for plate 7
Creating thread for customer 0
Creating thread for customer 1
Creating thread for customer 2
Creating thread for customer 3
Creating thread for customer 4
Creating thread for customer 5
Creating thread for customer 6
Creating thread for customer 7
Creating thread for customer 8
Creating thread for customer 9
Customer 6 is eating
Customer 7 is eating
Illegal instruction (core dumped)

用线

pthread_create(&customer[j],NULL,(void *)eat,&j);

您将变量j的地址作为参数传递给线程。 然后,您将相同的地址传递给所有线程的相同变量。

循环结束后, j的值将等于customer_count ,这就是线程可能用作数组索引的内容。 而且它的诅咒超出范围导致未定义的行为

对于一种可能的解决方案,实际上是在一个地方将整数值转换为指针,然后在线程中将其转换回来。 但是,这必须分两步完成。 首先创建线程:

pthread_create(&customer[j],NULL,(void *)eat, (void *) (intptr_t) j);

然后在线程本身中:

int n = (int) (intptr_t) i;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM