简单的多线程流水线模型(二)

1 篇文章 0 订阅

续上一篇《简单的多线程流水线模型(一)》

下面我们创建三个工人 Lucy,Lily,Lilei,他们干的活就是接收输入的秒数input,把睡眠input秒,然后把input-1丢给下一个工人。

这里做一下小结:

流水线模型的优缺点。

优点:一环扣一环,确保事情按顺序一个一个干完。

缺点:流水线的某个环节如果处理速度慢的话,会影响上游的整个流水线,所以流水线的瓶颈应该是花时间最多的那个环节。如何调度,这个后面再讨论。

下面的实现多个工人的流水线,这里是假设每个工人干的活差不多,实际使用的时候,可以为每个环节写不同的thread_worker,这样就可以做一些更灵活的工作了!

代码如下:

#include <pthread.h>
#include <time.h>
#include "errors.h"

#define WORKERS_TOTAL 3

struct worker_type{
	pthread_mutex_t  mtx;
	pthread_cond_t cond_has_input;
	pthread_cond_t cond_has_finished;
	int has_input;
	int has_finished;

	pthread_t thread_id;
	void * (*thread_worker)(void *);// The thread of this worker
	struct worker_type * next;

	//below if optionally, corresponding to your demands
	char *name;                     // The worker's name
	int  input_data;                // The input data

};
typedef struct worker_type worker_t;

typedef struct pipeline_type{
	int       count;
    worker_t * head;
    worker_t * tail;
}pipeline_t;

void * send_input_to_worker(worker_t *worker, int input)
{
    //1. Catch the lock
	pthread_mutex_lock(&worker->mtx);

	//2. Waiting for the worker finish the job
	while(!worker->has_finished){
		pthread_cond_wait(&worker->cond_has_finished,&worker->mtx);
	}

	//3. Pass the input to the worker.
	worker->has_input = 1;
	worker->has_finished = 0;
	worker->input_data = input;
	pthread_cond_signal(&worker->cond_has_input);

	//4. Unlock
	pthread_mutex_unlock(&worker->mtx);
	return NULL;
}
void * thread_worker(void *arg)
{
    //1. Before looping ,do something initial.
    worker_t * worker = (worker_t *)arg;
    struct timespec t;
	int status;
	int input;
	t.tv_nsec = 0;
	//2. Looping
    while(1){
	    //2.1 Lock the worker before access its value
		pthread_mutex_lock(&worker->mtx);

        //2.2 Waiting for the input
	    while(!worker->has_input){
			printf("%s: Give me the job!\n",worker->name);
			status = pthread_cond_wait(&worker->cond_has_input,&worker->mtx);
		}

		//2.3 Fetch the input,processing
		input = worker->input_data;
		printf("%s: %d received! Process %d seconds\n",worker->name,input,input);
		sleep(input);//process
		if(worker->next != NULL){
			send_input_to_worker(worker->next,input-1);
		}else{
			printf("%s: Nobody works for me!\n",worker->name);
		}
		worker->has_input = 0;
		worker->has_finished = 1;

		//2.4 After processing, send the signal and unlock the mutex
		pthread_cond_signal(&worker->cond_has_finished);
		pthread_mutex_unlock(&worker->mtx);
	}
}

void *pipe_line_start(pipeline_t * pipeline_p)
{
	worker_t *worker_p, **worker_pp;
	char * names[] = {"Lucy ","Lily ","Lilei"};
    int i;

	worker_pp = &pipeline_p->head;
	for(i = 0; i < WORKERS_TOTAL ;i++){
		*worker_pp = (worker_t *)malloc(sizeof(worker_t));
		worker_p = *worker_pp;

		worker_p->name = names[i];
		worker_p->thread_worker = thread_worker;
		worker_p->has_input = 0;
		worker_p->has_finished = 1;
		pthread_mutex_init(&worker_p->mtx,NULL);
		pthread_cond_init(&worker_p->cond_has_input,NULL);
		pthread_create(&worker_p->thread_id,NULL,worker_p->thread_worker,worker_p);

		worker_pp = &worker_p->next;
	}
	pipeline_p->tail = *worker_pp;
	worker_p->next = NULL;

	return NULL;
}
int main(int argc, char *argv[]){
    int i;
    pipeline_t pipeline1,;
	pipe_line_start(&pipeline1);

	while(1){
		scanf("%d",&i);	
		send_input_to_worker(pipeline1.head,i);
	}
	pthread_exit(NULL);
	return 0;
}

输出结果:

[hackooo@localhost c]$ gcc -lpthread ti.c 
[hackooo@localhost c]$ ./a.out 
Lilei: Give me the job!
Lily : Give me the job!
Lucy : Give me the job!
4
Lucy : 4 received! Process 4 seconds      //等待4秒
Lucy : Give me the job!
Lily : 3 received! Process 3 seconds        //等待3秒
Lily : Give me the job!
Lilei: 2 received! Process 2 seconds       //等待2秒
Lilei: Nobody works for me!
Lilei: Give me the job!
^C
[hackooo@localhost c]$ 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一段C多线程流水线模型推理代码的示例: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NUM_THREADS 4 typedef struct { int *input; int *output; int size; } PipelineData; void *stage1(void *arg) { PipelineData *data = (PipelineData *) arg; for (int i = 0; i < data->size; i++) { data->output[i] = data->input[i] * 2; } pthread_exit(NULL); } void *stage2(void *arg) { PipelineData *data = (PipelineData *) arg; for (int i = 0; i < data->size; i++) { data->output[i] = data->input[i] + 1; } pthread_exit(NULL); } void *stage3(void *arg) { PipelineData *data = (PipelineData *) arg; for (int i = 0; i < data->size; i++) { data->output[i] = data->input[i] - 3; } pthread_exit(NULL); } void *stage4(void *arg) { PipelineData *data = (PipelineData *) arg; for (int i = 0; i < data->size; i++) { data->output[i] = data->input[i] / 2; } pthread_exit(NULL); } int main() { int input[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int output[10]; pthread_t threads[NUM_THREADS]; PipelineData data[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { data[i].input = (i == 0) ? input : output; data[i].output = (i == NUM_THREADS - 1) ? output : (int *) malloc(sizeof(int) * 10); data[i].size = 10; pthread_create(&threads[i], NULL, (i == 0) ? stage1 : (i == 1) ? stage2 : (i == 2) ? stage3 : stage4, (void *) &data[i]); } for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); if (i != NUM_THREADS - 1) { free(data[i].output); } } for (int i = 0; i < 10; i++) { printf("%d ", output[i]); } printf("\n"); return 0; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值