Я написал этот код для создания двух файлов .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;