Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅使用互斥量和信号量的生产者-消费者同步(无pthread_cond)_C_Linux_Pthreads - Fatal编程技术网

仅使用互斥量和信号量的生产者-消费者同步(无pthread_cond)

仅使用互斥量和信号量的生产者-消费者同步(无pthread_cond),c,linux,pthreads,C,Linux,Pthreads,我目前正在学习如何使用互斥量和信号量在linux中使用pthreads进行多线程处理,并且我一直在研究Multi producer/one Consumer问题的一个实现,仅使用两个二进制信号量和一个互斥量来同步对有界缓冲区的访问,但该程序没有按计划工作 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <math.h> #include <semaphor

我目前正在学习如何使用互斥量和信号量在linux中使用pthreads进行多线程处理,并且我一直在研究Multi producer/one Consumer问题的一个实现,仅使用两个二进制信号量和一个互斥量来同步对有界缓冲区的访问,但该程序没有按计划工作

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

#define QUEUESIZE 20
#define LOOP 15
#define MAX_THREADS 10

void *producer (void *args);
void *consumer (void *args);

int lambda;
int queuesi;
typedef struct {
        int buf[QUEUESIZE];
        long head, tail;
        int full, empty;
        pthread_mutex_t *mut; 
    sem_t *sem_notFull, *sem_notEmpty;
} queue;

queue *queueInit (void);
void queueDelete (queue *q);
void queueAdd (queue *q, int in);
void queueDel (queue *q, int *out);
int factorial( int i);           
int poissonfunction(int i);
int rando();

int main (int argc, char *argv[])
{
        int max_pro,max_con,j,i;
        queue *fifo;
        pthread_t prod[MAX_THREADS],cons[MAX_THREADS];

        max_con=1;
        max_pro=4;
        lambda=6;
        queuesi=4;  

        fifo = queueInit ();

        if (fifo ==  NULL) {
                fprintf (stderr, "main: Queue Init failed.\n");
                exit (1);
        }


        for(i=0; i<max_pro;i++)  
        pthread_create (&prod[i], NULL, producer,fifo);

        for(j=0;j<max_con;j++)
        pthread_create (&cons[j], NULL, consumer, fifo);

        for(i=0; i<max_pro;i++)
        pthread_join (prod[i], NULL);

        for(j=0;j<max_con;j++)
        pthread_join (cons[j], NULL);     

        queueDelete (fifo);

        return 0;
}

 void *producer (void *q)
{
        queue *fifo;
        int i,insert,sleep_time;     
        fifo = (queue *)q;

        for (i = 0; i < LOOP; i++) {
            //pthread_mutex_lock (fifo->mut);
            while (fifo->full)
               {
                    printf ("producer: queue FULL.\n");
                    sem_wait (fifo->sem_notFull);
                }

             pthread_mutex_lock (fifo->mut);
             insert=rando();     
             queueAdd (fifo, insert);  
             printf("producer item  number%d item produced  %d\n",i,insert);
             pthread_mutex_unlock (fifo->mut);

             sem_post (fifo->sem_notEmpty);
             sleep_time=poissonfunction(i);
             usleep (sleep_time);
        }

        return (NULL);
}                           

 void *consumer (void *q)
{
        queue *fifo;
        int i, d;

        fifo = (queue *)q;

        for (i = 0; i < LOOP; i++) 
        {
            //pthread_mutex_lock (fifo->mut);
            while (fifo->empty) 
            {      
               printf ("consumer: queue empty\n");
               sem_wait (fifo->sem_notEmpty);
            }
            pthread_mutex_lock (fifo->mut);
            queueDel (fifo, &d);
            pthread_mutex_unlock (fifo->mut);

            sem_post (fifo->sem_notFull);
            printf ("consumer: recieved %d.\n", d);
            usleep(2000);
        }                 

  return (NULL);
}

queue *queueInit (void)
{
        queue *q;

        q = (queue *)malloc (sizeof (queue));
        if (q == NULL) return (NULL);       
        q->empty = 1;
        q->full = 0;
        q->head = 0;
        q->tail = 0;
        q->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t));
        pthread_mutex_init (q->mut, NULL);
    q->sem_notFull = (sem_t *) malloc (sizeof (sem_t));
        sem_init (q->sem_notFull, 0, 1);
        q->sem_notEmpty = (sem_t *) malloc (sizeof (sem_t));
        sem_init (q->sem_notEmpty,  0, 1); 

        return (q);
}

void queueDelete (queue *q)
{
        pthread_mutex_destroy (q->mut);
        free (q->mut);
        sem_destroy (q->sem_notFull);
        free (q->sem_notFull);   

        sem_destroy (q->sem_notEmpty);
        free (q->sem_notEmpty);

        free (q);
}

void queueAdd (queue *q, int in)
{
        q->buf[q->tail] = in;
        q->tail++;
        if (q->tail == queuesi)                     
        q->tail = 0;

        if (q->tail == q->head)
                q->full = 1;
        q->empty = 0;

        return;
}

void queueDel (queue *q, int *out)
{                                       
*out = q->buf[q->head];

        q->head++;
        if (q->head == queuesi)
                q->head = 0;
        if (q->head == q->tail)
                q->empty = 1;
        q->full = 0;

        return;                    
}

int factorial(int i){
 if(i==0)
  return i=1;
 else
  i=i*factorial(i-1);
return (i);
}               

int poissonfunction (int i){
    int time,c,t;
    double p;
    t = 1000;
    c = lambda*t;
    p = (pow(c,i)*exp(-c))/factorial(i);
    time =(int) p*t;
    return (time);
}

int rando(){
    int value;
    value=(int) random()/1000;
    return (value);
}
#包括
#包括
#包括
#包括
#包括
#定义队列大小20
#定义循环15
#定义最多10个线程
无效*生产者(无效*参数);
无效*消费者(无效*参数);
int lambda;
int-queuesi;
类型定义结构{
int buf[队列大小];
头、尾长;
int满,空;
pthread_mutex_t*mut;
sem_t*sem_notFull,*sem_notEmpty;
}排队;
队列*queueInit(无效);
void queueDelete(queue*q);
void queueAdd(队列*q,整数in);
void queueDel(队列*q,整数*out);
整数阶乘(inti);
int泊松函数(inti);
int rando();
int main(int argc,char*argv[])
{
int max_pro,max_con,j,i;
队列*fifo;
pthread_t prod[MAX_THREADS],cons[MAX_THREADS];
max_con=1;
max_pro=4;
λ=6;
队列si=4;
fifo=queueInit();
如果(fifo==NULL){
fprintf(stderr,“main:Queue Init失败。\n”);
出口(1);
}
对于(i=0;imut);
insert=rando();
队列添加(fifo,插入);
printf(“生产商物料编号%d生产的物料%d\n”,i,插入);
pthread_mutex_unlock(fifo->mut);
sem_post(先进先出->sem_notEmpty);
睡眠时间=泊松函数(i);
usleep(睡眠时间);
}
返回(空);
}                           
void*consumer(void*q)
{
队列*fifo;
int i,d;
fifo=(队列*)q;
for(i=0;imut);
while(先进先出->空)
{      
printf(“使用者:队列为空\n”);
sem\u wait(先进先出->sem\u notEmpty);
}
pthread_mutex_lock(fifo->mut);
队列删除(fifo和d);
pthread_mutex_unlock(fifo->mut);
sem\U post(先进先出->sem\U未满);
printf(“消费者:收到%d.\n”,d);
usleep(2000年);
}                 
返回(空);
}
队列*queueInit(无效)
{
队列*q;
q=(队列*)malloc(sizeof(队列));
如果(q==NULL)返回(NULL);
q->空=1;
q->full=0;
q->head=0;
q->tail=0;
q->mut=(pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(q->mut,NULL);
q->sem_notFull=(sem_t*)malloc(sizeof(sem_t));
sem_init(q->sem_notFull,0,1);
q->sem_notEmpty=(sem_t*)malloc(sizeof(sem_t));
sem_init(q->sem_notEmpty,0,1);
回报率(q);
}
void queueDelete(队列*q)
{
pthread_mutex_destroy(q->mut);
自由(q->mut);
扫描电镜破坏(q->扫描电镜未满);
免费(q->sem\U未满);
sem_破坏(q->sem_notEmpty);
免费(q->sem\u notEmpty);
免费(q);
}
void queueAdd(队列*q,整数in)
{
q->buf[q->tail]=in;
q->tail++;
如果(q->tail==queuesi)
q->tail=0;
如果(q->tail==q->head)
q->full=1;
q->空=0;
返回;
}
void queueDel(队列*q,整数*out)
{                                       
*out=q->buf[q->head];
q->head++;
如果(q->head==queuesi)
q->head=0;
如果(q->head==q->tail)
q->空=1;
q->full=0;
返回;
}
整数阶乘(整数i){
如果(i==0)
返回i=1;
其他的
i=i*阶乘(i-1);
回报(i);
}               
整数泊松函数(整数i){
整数时间,c,t;
双p;
t=1000;
c=λ*t;
p=(pow(c,i)*exp(-c))/阶乘(i);
时间=(int)p*t;
返回(时间);
}
int rando(){
int值;
值=(int)random()/1000;
回报(价值);
}

我建议修改您的函数,如:

void *producer (void *q)
{   
    queue *fifo;
    int i,insert,sleep_time;
    fifo = (queue *)q;

    for (i = 0; i < LOOP; i++) {
        pthread_mutex_lock (fifo->mut); /* take lock */
        while (fifo->full) {  /* check for fullness */
            pthread_mutex_unlock (fifo->mut); /* if full wait for things to be removed */
            sem_wait (fifo->sem_notFull); /* never sleep with lock */
            pthread_mutex_lock (fifo->mut); /* take lock an recheck the condition to handle spurious wakeups */
        }
        /* here lock is held */
        insert = rando(); /* safely manipulate the queue */
        queueAdd (fifo, insert);

        pthread_mutex_unlock (fifo->mut); /* safely release the queue */
        sem_post (fifo->sem_notEmpty);  /* wake up potential waiters */
        sleep_time=poissonfunction(i);
        usleep (sleep_time);
    }

    return (NULL);
}

void *consumer (void *q)
{
    queue *fifo;
    int i, d;

    fifo = (queue *)q;

    for (i = 0; i < LOOP; i++) { /* careful you don't produce 'enough' */
        pthread_mutex_lock (fifo->mut); /* take lock before using fifo */
        while (fifo->empty) { /* check is something to read */
            pthread_mutex_unlock (fifo->mut); /* release lock before sleep */
            sem_wait (fifo->sem_notEmpty); /* wait a sometihing to be pused in queue */
            pthread_mutex_lock (fifo->mut); /* take back lock before checking for spurious wakeup */
        }
        /* from here lock is held, queue can be safely maniplated */
        queueDel (fifo, &d); 
        pthread_mutex_unlock (fifo->mut); /* finished -> release lock */
        sem_post (fifo->sem_notFull); /* wake up eventual waiters*/

        usleep(2000);
    }

    return (NULL);
}
void*producer(void*q)
{   
队列*fifo;
int i,插入,睡眠时间;
fifo=(队列*)q;
for(i=0;imut);/*获取锁*/
而(fifo->full){/*检查是否已满*/
pthread_mutex_unlock(fifo->mut);/*如果已满,请等待删除内容*/
sem_wait(fifo->sem_notFull);/*永远不要带锁睡觉*/
pthread_mutex_lock(fifo->mut);/*获取锁并重新检查处理虚假唤醒的条件*/
}
/*这里有锁*/
insert=rando();/*安全地操作队列*/
队列添加(fifo,插入);
pthread_mutex_unlock(fifo->mut);/*安全释放队列*/
sem_post(先进先出->sem_notEmpty);/*唤醒潜在的服务员*/
睡眠时间=泊松函数(i);
usleep(睡眠时间);
}
返回(空);
}
void*consumer(void*q)
{
队列*fifo;
int i,d;
fifo=(队列*)q;
对于(i=0;imut);/*在使用fifo之前先锁定*/
而(fifo->empty){/*check是一个值得阅读的东西*/
pthread_mutex_unlock(fifo->mut);/*睡眠前释放锁*/
sem_wait(fifo->sem_notEmpty);/*在队列中等待一些东西*/
pthread_mutex_lock(fifo->mut);/*在检查虚假唤醒之前收回锁*/
}
/*从这里锁上,可以安全地操纵队列*/
队列删除(fifo和d);
pthread_mutex_unlock(fifo->mut);/*完成->释放锁*/
sem_post(先进先出->sem_notFull);/*唤醒最终的服务员*/
usleep(2000年);
}
返回(空);
}
您需要检查虚假的唤醒,因为信号量是