【问题标题】:How to implement semaphores with threads without global variables如何使用没有全局变量的线程实现信号量
【发布时间】:2017-05-11 13:08:48
【问题描述】:

我当前的代码回答了生产者消费者的问题,但我想以不同的方式实现它。我不想使用全局变量来跟踪缓冲区堆栈中的计数。我的思考过程应该是什么?

typedef int semaphore;
semaphore mutex, full, empty;

int count = 0;

    union semun {
        int val;
        struct semid_ds *buf;
        unsigned short      *array; 
    } arg;


int buffer[N];

这些是使用count的函数

int remove_item()
{
    int ret = buffer[--count];
    buffer[count] = 0;
    return ret;
}

void insert_item(int item)
{
    buffer[count++] = item;
}

int produce_item(){
    int item = rand()%50 +1;
    printf("Producer produces %d\n",item);
    sleep(1);
    return item;
}

还有我的生产者消费者函数

void* consumer(void * arg) {
    int item = 0;
    while(1){
        down(full);
        down(mutex);    
        item = remove_item();
        buffer[count++] = item; 
        up(mutex);
        up(empty);
        consume_item(item);
    }
    return 0;
}

void* producer(void* arg) { 
    int item, i =0;
    while(1){
        item  = produce_item();
        down(empty);
        down(mutex);
        insert_item(item);
        up(mutex);
        up(full);
        sleep(1);

    }

【问题讨论】:

  • 计数、三个信号量和缓冲区空间都属于一个'PCqueue'结构。您需要一个函数来返回一个已初始化的函数(或指向它的指针)。然后可以轻松地将结构提升到任何线程的堆栈上。
  • 发布的代码没有实现任何信号量。由此产生的race 条件将导致数据损坏、丢失、重复。

标签: c multithreading semaphore producer-consumer


【解决方案1】:

通常的方式是将线程使用的变量作为参数传递。大多数线程库(POSIX pthread、Windows CreateThread 等)通过允许指向任何形式数据的 void 指针在创建时传递给线程来支持这一点 - 这就是线程回调函数中的“arg”参数的用途。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 2023-04-07
    • 2012-05-16
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多