C:使用来自单独文件的函数

标签 c linux synchronization pthreads

尝试使用来 self 编码的单独文件的有界缓冲区,似乎这就是代码变得疯狂的地方。 C 相当新,我想知道我是否以正确的方式使用缓冲区。实例化的概念不在这里,所以如果我只调用函数之一,例如 bbuff_blocking_insert 数组会被初始化吗?我如何进行适当的调用才能使其正常工作?

糖果.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "bbuff.h"
#include <stdbool.h>
#include <time.h>

_Bool stop_thread = false;

typedef struct {
    int source_thread;
    double time_stamp_in_ms;
} candy_t;

double current_time_in_ms (void) {
    struct timespec now;
    clock_gettime(CLOCK_REALTIME, &now);
    return now.tv_sec * 1000.0 + now.tv_nsec/1000000.0;
}

void* createCandy(void* arg) {
    int r;
    int factoryNumber = *(int*)arg;
    while(!stop_thread) {
        r = rand() % 4;
        printf("Random Number: %d\n", r);
        printf("\tFactory %d ship candy & wait %ds\n", factoryNumber, r);
        candy_t *candy = (candy_t*)malloc(sizeof(candy_t));
        candy->source_thread = factoryNumber;
        candy->time_stamp_in_ms = current_time_in_ms();
        bbuff_blocking_insert((void *)candy);
        sleep(r);
    }
    printf("Candy-factory %d done\n", factoryNumber);
    return 0;
}

void* extractCandy(void* arg) {
    int r;
    candy_t* candy;
    while(true) {
        candy = (candy_t*)bbuff_blocking_extract();
        printf("Candy Source Thread: %d\n", candy->source_thread);
        r = rand() % 2;
        sleep(r);
    }
    return 0;
}


int main(int argc, char* argv[]) {
    //Extract Arguments
    if (argc <= 1) {
        printf("Insufficient Arguments\n");
        exit(-1);
    }
    int NO_FACTORIES = atoi(argv[1]);
    int NO_KIDS = atoi(argv[2]);
    int NO_SECONDS = atoi(argv[3]);

    bbuff_init();

    //Spawn Factory Threads
    pthread_t ftids[NO_FACTORIES];
    int factoryNumber[NO_FACTORIES];
    for (int i = 0; i < NO_FACTORIES; i++) {
        factoryNumber[i] = i;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_create(&ftids[i], &attr, createCandy, &factoryNumber[i]);
    }

    //Spawn Kid Threads
    pthread_t ktids [NO_KIDS];
    for (int i = 0; i < NO_KIDS; i++) {
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_create(&ktids[i], &attr, extractCandy, NULL);
    }

    //Wait for Requested Time
    for (int i = 0; i < NO_SECONDS; i++) {
        sleep(1);
        printf("Time %ds\n", i+1);
    }

    //Stop Factory Threads
    stop_thread = true;
    for (int i = 0; i < NO_FACTORIES; i++) {
        pthread_join(ftids[i], NULL);
    }
    //Wait until no more candy
    while(bbuff_is_data_available()) {
        printf("Waiting for all candy to be consumed");
        sleep(1);
    }
    //Stop kid Threads
    for (int i = 0; i < NO_KIDS; i++) {
        pthread_cancel(ktids[i]);
        pthread_join(ktids[i], NULL);
    }
    //Print Statistics
    //Clean up any allocated memory

    return 0;
}

bbuff.h

#ifndef BBUFF_H
#define BBUFF_H

#define QUEUE_SIZE 10

void bbuff_init(void);
void bbuff_blocking_insert(void* item);
void* bbuff_blocking_extract(void);
_Bool bbuff_is_data_available(void);

#endif

bbuff.c

#include "bbuff.h"
pthread_mutex_t mutex;
sem_t empty;
sem_t full;
int in = 0;
int out = 0;
int counter = 0;
void* buffer[QUEUE_SIZE];

void bbuff_init(void){
    pthread_mutex_init(&mutex, NULL);
    sem_init( &empty, 0, QUEUE_SIZE);
    sem_init( &full, 0, 0);
}

void bbuff_blocking_insert(void* item) {
    sem_wait(&empty);
    pthread_mutex_lock(&mutex);
    counter++;
    buffer[in] = item;
    in = (in+1) % QUEUE_SIZE;
    pthread_mutex_unlock(&mutex);
    sem_post(&full);
}

void* bbuff_blocking_extract(void) {
    void* extractedItem;
    sem_wait(&full);
    pthread_mutex_lock(&mutex);
    counter--;
    extractedItem = buffer[out];
    buffer[out] = NULL;
    out = out % QUEUE_SIZE;
    pthread_mutex_unlock(&mutex);
    sem_post(&empty);
    return extractedItem;
}

输出

$ ./candykids 1 1 10
Random Number: 3
    Factory 0 ship candy & wait 3s
Candy Source Thread: 0
Time 1s
Time 2s
Random Number: 1
    Factory 0 ship candy & wait 1s
Time 3s
Segmentation fault (core dumped)

最佳答案

bbuff_blocking_extract() 中,

out = out % QUEUE_SIZE;

应该是:

out = (out+1) % QUEUE_SIZE;

关于C:使用来自单独文件的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29138861/

相关文章:

Linux:减号 -* 在 bash 脚本中意味着什么

linux - GREP 或 AWK : Search in the first N characters of each line, 并输出匹配模式的周围行

android - "Too many open files"- 无法删除目录

java - SymmetricDS 如何在转换期间过滤行

node.js - Ubuntu 中的 cp 命令 - 同步

c - 在 C 中是否以这种方式释放结构?

c - Thales Connect HSM - DeriveKey 操作

c - 在c中编辑字符串数组

java - 使用同步(锁定对象) block 时,静态锁定对象是否需要是最终的?

c++ - 我应该学习 GTK+ 还是 GTKMM?