Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中使用带有pthreads的全局结构_C_Multithreading_Struct_Pthreads_Simulation - Fatal编程技术网

在C中使用带有pthreads的全局结构

在C中使用带有pthreads的全局结构,c,multithreading,struct,pthreads,simulation,C,Multithreading,Struct,Pthreads,Simulation,我试图模拟客户进入银行,并在一段时间内接受出纳员的服务。我使用一个线程来确定客户是否通过到达率进入银行,并使用多个线程来表示具有s服务率的出纳员。我使用struct来保存时间段、到达率、服务率、出纳员数量和客户等待队列。我试图在所有线程之间共享该结构,但出现“取消引用指针”错误和“请求非结构中的成员x”错误 信息通过从命令行传递到结构中 struct shiftInfo *Q = malloc(sizeof(struct shiftInfo) + (maxCust*sizeof(int)

我试图模拟客户进入银行,并在一段时间内接受出纳员的服务。我使用一个线程来确定客户是否通过到达率进入银行,并使用多个线程来表示具有s服务率的出纳员。我使用struct来保存时间段、到达率、服务率、出纳员数量和客户等待队列。我试图在所有线程之间共享该结构,但出现“取消引用指针”错误和“请求非结构中的成员x”错误

信息通过从命令行传递到结构中

    struct shiftInfo *Q = malloc(sizeof(struct shiftInfo) + (maxCust*sizeof(int)));
    struct shiftInfo info;
    info.simTime = atoi(argv[1]);
    info.arrivalRate = atof(argv[2]);
    info.tellers = atoi(argv[3]);
    info.serviceTime = atoi(argv[4]);
    info.sampleInterval = atoi(argv[5]);
    //Initiates Q to 0
    for (int i = 0; i < maxCust; i++)
        info.Q[i] = 0;
为了简短起见,我将只询问计时器线程,并希望将答案应用于其他线程。计时器线程通过以下方式在主线程中创建:

  int status;
  struct shiftInfo *I = info; 
  pthread_t time;
      status = pthread_create(&time, NULL, timer, (void *)info);
      if (status){
        printf("ERROR CODE: %d\n", status);
        exit(-1);
    }
定时器线程函数为:

void *timer(void *info){
    int timeRemaining = info -> simTime;
    while(timeRemaining){
        sleep(1);
        timeRemaining--;
        }
}
对于“int timeRemaining=info->simTime;”,我得到了警告“取消引用void指针”和对成员–simTime–的错误请求,它们不是结构或联合。 任何建议都将不胜感激

此外,我创建客户线程的方式与创建计时器线程的方式相同,但收到了一个警告(警告:传递参数3–pthread_create–makes pointer from integer而不使用强制转换[默认情况下启用]),而我在创建任何其他线程时没有收到该警告,这是什么原因造成的

pthread_t customer;
    status = pthread_create(&customer, NULL, customer, (void *)info);
        if (status){
            printf("ERROR CODE: %d\n", status);
            exit(-1);
        }

这个片段有问题:

struct shiftInfo *Q = malloc(sizeof(struct shiftInfo) + (maxCust*sizeof(int)));
struct shiftInfo info;
info.simTime = atoi(argv[1]);
info.arrivalRate = atof(argv[2]);
info.tellers = atoi(argv[3]);
info.serviceTime = atoi(argv[4]);
info.sampleInterval = atoi(argv[5]);
//Initiates Q to 0
for (int i = 0; i < maxCust; i++)
    info.Q[i] = 0;
现在,您可以使用
shift
(或您选择的任何名称)设置全局指针。请注意,不能将具有灵活数组成员的结构作为全局变量(指向它们的全局指针-是;全局变量-否),也不能将它们作为自动变量。问题是您无法为这样的灵活数组成员分配任何空间

您需要考虑如何控制对多个线程的全局结构的访问,以及对全局结构的序列化访问是否会成为严重的瓶颈。您可能需要一个互斥锁,可能还需要一些条件

至于您的
计时器
代码:您需要转换传递到
结构ShiftInfo*
void*

void *timer(void *vp)
{
    struct ShiftInfo *info = vp;
    int timeRemaining = info->simTime;
    while(timeRemaining){
        sleep(1);
        timeRemaining--;
        }
    return 0;
}
请注意,您确实需要从函数返回一个值。此外,你需要考虑这是否会实现你想要的。它有一个已更改的局部变量。您可能需要将
info
中的值设置为剩余时间。这需要每个操作都有互斥访问。我假设您添加并初始化了一个额外的成员:

pthread_t mutex;
到您的
结构shiffinfo

void *timer(void *vp)
{
    struct shiftInfo *info = vp;
    if (pthread_mutex_lock(&info->mutex) != 0)
        return 0;  // Report error before returning?
    int *timeRemaining = &info->simTime;
    while (*timeRemaining > 0)
    {
        if (pthread_mutex_unlock(&info->mutex) != 0)
            return 0;  // Report error before returning?
        sleep(1);
        if (pthread_mutex_lock(&info->mutex) != 0)
            return 0;  // Report error before returning?
        (*timeRemaining)--;
    }
    if (pthread_mutex_unlock(&info->mutex) != 0)
        return 0;  // Report error before returning?
    return 0;
}

你犯了不少错误和打字错误。第一个错误是:

struct shiftInfo *Q = malloc(sizeof(struct shiftInfo) + (maxCust*sizeof(int)));
struct shiftInfo info;
info.simTime = atoi(argv[1]);
info.arrivalRate = atof(argv[2]);
info.tellers = atoi(argv[3]);
info.serviceTime = atoi(argv[4]);
info.sampleInterval = atoi(argv[5]);
//Initiates Q to 0
for (int i = 0; i < maxCust; i++)
    info.Q[i] = 0;
void *timer(void *info){
    int timeRemaining = info -> simTime;
下一个错误是:

status = pthread_create(&time, NULL, timer, (void *)info);
在代码中,
info
是一个结构。但你正试图把它投射到一个指针上。如果您使用我上面建议的修复方法,
info
将是一个指针,您可以保持此代码不变。您需要确保对
pthread\u create
pass
(void*)info
,而不是
(void*)info

void *timer(void *vp)
{
    struct shiftInfo *info = vp;
    if (pthread_mutex_lock(&info->mutex) != 0)
        return 0;  // Report error before returning?
    int *timeRemaining = &info->simTime;
    while (*timeRemaining > 0)
    {
        if (pthread_mutex_unlock(&info->mutex) != 0)
            return 0;  // Report error before returning?
        sleep(1);
        if (pthread_mutex_lock(&info->mutex) != 0)
            return 0;  // Report error before returning?
        (*timeRemaining)--;
    }
    if (pthread_mutex_unlock(&info->mutex) != 0)
        return 0;  // Report error before returning?
    return 0;
}
最后一个错误是:

struct shiftInfo *Q = malloc(sizeof(struct shiftInfo) + (maxCust*sizeof(int)));
struct shiftInfo info;
info.simTime = atoi(argv[1]);
info.arrivalRate = atof(argv[2]);
info.tellers = atoi(argv[3]);
info.serviceTime = atoi(argv[4]);
info.sampleInterval = atoi(argv[5]);
//Initiates Q to 0
for (int i = 0; i < maxCust; i++)
    info.Q[i] = 0;
void *timer(void *info){
    int timeRemaining = info -> simTime;
请尝试以下方法:

void *timer(void *arg){
    struct shiftInfo *info = (struct shiftInfo *) arg;
    int timeRemaining = info -> simTime;
在timer()函数中,必须将info参数从(void*)强制转换为(struct shiftInfo*)

另外,在创建客户时,应该是这样的

status = pthread_create(&customer, NULL, customer, (void *)&info);

谢谢你的回复,我做了建议的更改,正如现在在这篇文章中看到的,但是我仍然收到类似的错误和警告。另外,我也不太担心对结构的访问,因为唯一改变的方面是计时器和客户Q,尽管我不知道如何确保两个出纳员不尝试获取相同的客户。通过确保线程访问数据结构时的互斥,可以确保两个出纳员不尝试获取相同的客户。您可以设计具有多个互斥体的方案来控制对结构不同部分的访问,但最低要求是一个互斥体。对于访问全局变量的多线程应用程序,您必须非常小心。谢谢,我要补充的是,一旦我启动并运行了核心代码,我不认为这会导致问题,因为这更像是一个错误的结果错误,而不是编译器问题。谢谢,我提出了您的前两个更改建议,正如现在在文章中看到的,但是对void*timer的更改似乎使simTime成为一个局部变量,我希望计时器对simTime所做的更改能够从所有线程读取。根本不要使用
timeRemaining
。只需使用
info->simTime
。对
info->simTime
的任何更改都应该对所有线程可见,因为您在
pthread\u create
中向每个线程传递了相同的
info
。您是否建议使用类似于“void*timer(void*arg){struct shiftInfo*info=(struct shiftInfo*)arg而(info->simTime){sleep(1);(info->simTime)}“这似乎消除了那一节中的错误,但我还有原帖中提到的其他错误@JS1I只是在学习多线程,有几个动态分配的数组需要传递给每个pthread。这个答案真的帮助我简化了代码,避免了重复不必要的数据。您关于timeRemaining的建议导致了错误“error:info–undeclared(首次在这个函数中使用)int-timeRemaining=((struct-shiftInfo*)info)->simTime;”,这难道不会使timeRemaining成为一个局部变量吗?我希望它可以从所有线程访问。另外,为什么不能像计时器功能一样将客户声明为“void*customer(void*info)”?对不起,当我阅读您的回复时,我显然非常累,感谢@Phuc-Nguyen V的建议。请不要改变问题,使答案无效!抱歉,我正在尝试用答案更新它以避免重复,我会将其更改回。
int timeRemaining = ((struct shiftInfo *)info) -> simTime;
status = pthread_create(&customer, NULL, customer, (void *)&info);