【问题标题】:Threads work inappropriately线程工作不正常
【发布时间】:2017-04-06 06:37:19
【问题描述】:

我正在用 c 编写这段代码

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

typedef struct
{
    int customerID;
    int ticketNumber;
    sem_t * freeCashiers;
    sem_t Cashiers[2];
}Customer;

int firstIsFree = 1;
int secondIsFree = 1;

void * buyTheTickets(void * data)
{
    Customer * currentCustomer = (Customer *)data;
    int ID = currentCustomer->customerID;

    currentCustomer->ticketNumber = rand()%15+1;

    sem_wait(currentCustomer->freeCashiers);    

    sem_wait(&(currentCustomer->Cashiers[0]));

    if(firstIsFree)
    {
        firstIsFree = 0;
        printf("First Cashier Sold %d Ticket To %d Customer\n",currentCustomer->ticketNumber,ID);

        usleep(1000000);
        firstIsFree = 1;

        sem_post(&(currentCustomer->Cashiers[0]));
        sem_post(currentCustomer->freeCashiers);

        return 0;
    }

    sem_post(&(currentCustomer->Cashiers[0]));

    sem_wait(&(currentCustomer->Cashiers[1]));

    if(secondIsFree)
    {
        secondIsFree = 0;
        printf("Second Cashier Sold %d Ticket To %d Customer\n",currentCustomer->ticketNumber,ID);

        usleep(1000000);
        secondIsFree = 1;

        sem_post(&(currentCustomer->Cashiers[1]));
        sem_post(currentCustomer->freeCashiers);

        return 0;
    }
    sem_post(&(currentCustomer->Cashiers[1]));
}

int main()
{
    int numberOfCustomers = 15;
    sem_t * numberOfCashiers = (sem_t*)malloc(sizeof(sem_t));
    sem_init(numberOfCashiers,0,2);
    sem_t first;
    sem_t second;
    sem_init(&first,0,1);
    sem_init(&second,0,1);

    for(int i=1;i<=numberOfCustomers;i++)
    {
        pthread_t * curTh = (pthread_t*)malloc(sizeof(pthread_t));
        Customer * curCu = (Customer *)malloc(sizeof(Customer));
        curCu->customerID = i;
        curCu->freeCashiers = numberOfCashiers;
        curCu->Cashiers[0] = first;
        curCu->Cashiers[1] = second;
        pthread_create(curTh,NULL,buyTheTickets,curCu);     
    }

    pthread_exit(0);
    return 0;
}

它给出了输出:

First Cashier Sold 14 Ticket To 1 Customer

Second Cashier Sold 2 Ticket To 2 Customer

First Cashier Sold 13 Ticket To 3 Customer

Second Cashier Sold 11 Ticket To 4 Customer

First Cashier Sold 9 Ticket To 5 Customer

Second Cashier Sold 11 Ticket To 6 Customer

First Cashier Sold 2 Ticket To 7 Customer

Second Cashier Sold 13 Ticket To 8 Customer

First Cashier Sold 10 Ticket To 9 Customer

Second Cashier Sold 2 Ticket To 10 Customer

First Cashier Sold 3 Ticket To 11 Customer

Second Cashier Sold 8 Ticket To 12 Customer

First Cashier Sold 6 Ticket To 13 Customer

Second Cashier Sold 5 Ticket To 14 Customer

First Cashier Sold 9 Ticket To 15 Customer

问题是,如果第二个线程跟在sem_wait(&amp;(currentCustomer-&gt;Cashiers[0])); 之后,这意味着sem_post(&amp;(currentCustomer-&gt;Cashiers[0])); 这已经发生了,所以 firstIsFree 已经是 1 那么为什么要打印第二个 printf 呢?

【问题讨论】:

  • 你想在什么场合穿上它? ... ;)
  • @LPs 没得到问题,这个领域的新人,你能换个方式问吗?
  • 好吧。这是个玩笑:inappropriate。我在看你的代码。如果我看到了什么,我会回来找你的。
  • 这个问题具有讽刺意味,指出您的代码格式不正确,因此难以阅读。
  • @LajosArpad 代码在我的编辑器中看起来不错,但是当我将其粘贴到这里时,它变得混乱,抱歉不是我的错。

标签: c multithreading struct pthreads posix


【解决方案1】:

您的代码中存在以下问题,可能导致未定义的行为。请更正它并再次尝试执行:

在您的主函数中,您正在使用信号量firstsecond 的局部变量,并且您的主函数似乎在不等待线程退出的情况下退出。您需要在主函数中调用 pthread_join

【讨论】:

  • 在主函数中添加一个循环,紧跟在您的 pthread_create 循环之后,并为所有创建的线程调用 pthread_join。
  • 你完全正确,但没有风险:这是一种具体的行为。
  • @LPs,你能进一步解释一下吗? “这是一种具体的行为”是什么意思?
  • 可能是个假朋友:我的意思是这是真实的行为:肯定在 pthread_exit(0); 之后无法访问两个主要具有本地范围的信号量
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多