Я компилирую этот файл c без ошибок и предупреждений, но при запуске он не возвращает никаких результатов - PullRequest
0 голосов
/ 08 мая 2018

Я написал этот код для создания двух файлов .txt (prod_in.txt, cons_out.txt). Я привожу этой программе три аргумента: во-первых, длину циклического буфера, во-вторых, сколько случайных чисел и в-третьих, начальное значение для метода rand_r. Эта программа использует два потока POSIX. Первый поток запускается подпрограммой Consumer, которая создает первый текстовый файл (cons_out.txt), заполняет его случайными числами и помещает это число в кольцевой буфер, а когда буфер заполнится, вызывает вторую угрозу. Второй запускает вторую подпрограмму Producer, которая читает числа из кольцевого буфера и записывает во второй файл .txt (prod_in.txt).

Я компилирую этот c-файл без ошибок и предупреждений, но когда я запускаю его, единственное, что нужно - создать два .txt и ничего больше. Но после этого он застрял в команде, и .txt оба они пусты.

Вот мой код. Спасибо !!!

 #include <pthread.h>
 #include <stdio.h>
 #include "circular_buffer.h"
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
 pthread_mutex_t lock; 
 circular_buffer *cb;
 struct producer_data{
int thread_id;
int seed;
int num;
}; 
//global variables
int file,file1;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
void cb_init(circular_buffer *cb, size_t capacity, size_t sz)
{
cb->buffer = malloc(capacity * sz);
if(cb->buffer == NULL){
    printf("Could not allocate memory..Exiting! \n");
    exit(1);
    }
    // handle error
cb->buffer_end = (char *)cb->buffer + capacity * sz;
cb->capacity = capacity;
cb->count = 0;
cb->sz = sz;
cb->head = cb->buffer;
cb->tail = cb->buffer;
}

//destroy circular buffer
void cb_free(circular_buffer *cb)
{
free(cb->buffer);
// clear out other fields too, just to be safe
}

//add item to circular buffer
void cb_push_back(circular_buffer *cb, const void *item)
{
if(cb->count == cb->capacity)
    {
        printf("Access violation. Buffer is full\n");
        exit(1);
    }
memcpy(cb->head, item, cb->sz);
cb->head = (char*)cb->head + cb->sz;
if(cb->head == cb->buffer_end)
    cb->head = cb->buffer;
cb->count++;
}

//remove first item from circular item
void cb_pop_front(circular_buffer *cb, void *item)
{
if(cb->count == 0)
    {
        printf("Access violation. Buffer is empy\n");
        exit(1);
}
memcpy(item, cb->tail, cb->sz);
cb->tail = (char*)cb->tail + cb->sz;
if(cb->tail == cb->buffer_end)
    cb->tail = cb->buffer;
cb->count--;
}

struct producer_data producer;
void *Producer(void *pro){

struct producer_data *my_data;
my_data=(struct producer_data *)pro;    
pthread_mutex_lock(&lock);  
while(cb->count<my_data->num)
pthread_cond_wait(&cond,&lock);
unsigned int see= (my_data->seed)*(my_data->thread_id);
for(int j=0;j<my_data->num;j++){    
int nu=rand_r(&see);
nu=nu%256;
cb_push_back(cb,(void*)&nu);
if(dup2(file,1)<0)exit(0);

printf("Producer %d: %d\n",my_data->thread_id,nu);
}
close(file);
pthread_mutex_unlock(&lock);


}
void *Consumer(void *id){
char *tmp_read=(char*)malloc(1);
pthread_mutex_lock(&lock);
int tid=(int) id;
while(cb->count>0){
    cb_pop_front(cb,(void*)tmp_read);
    if(dup2(file1,1)<0)exit(0);
    printf("Consumer %d: %d\n",tid,*tmp_read);
    free(tmp_read);
}
close(file1);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
}

int main(int argc, char **argv){
if (argc != 4){
    printf("Error: please give correct agrument.\n");
    return -1;
}
int s_size=atoi(argv[1]);
if(s_size<10){
    printf("error: the size of buffer must be greater of 10.\n");
    return -1;
}
int num=atoi(argv[2]);
if(num<1){
    printf("error: the 3rd agrument must be greater of 1.\n");
    return -1;
}
int seedp=atoi(argv[3]);
if(seedp<0){
    printf("error: the 4rd agrument must be greater of 0.\n");
    return -1;
}
int file =creat("prod_in.txt",0644);
int file1 =creat("cons_out.txt",0644);
if((file<0)||(file1<0))exit(0);

cb = (circular_buffer*)malloc(sizeof (struct circular_buffer));
cb_init(cb,num,1);
pthread_mutex_init(&lock,NULL); 
pthread_t threads,threads1;
producer.thread_id=1;
producer.seed=seedp;
producer.num=num;
int rc,rc1;
int i=1;
rc=pthread_create(&threads,NULL,Producer,(void *) &producer);
 if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
rc1=pthread_create(&threads1,NULL,Consumer,(void *)&i);
if (rc1){
    printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
pthread_join(threads,NULL);
pthread_join(threads1,NULL);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);

}   

Циркуляр_буффера.h:

 #include "stdio.h" 
 #include "sys/types.h"
 #include "stdlib.h"
 #include "string.h"

 typedef struct circular_buffer
 {
   void *buffer;     // data buffer
   void *buffer_end; // end of data buffer
   size_t capacity;  // maximum number of items in the buffer
   size_t count;     // number of items in the buffer
   size_t sz;        // size of each item in the buffer
   void *head;       // pointer to head
   void *tail;       // pointer to tail
   } circular_buffer;
...