进程与线程——Linux进程与线程通讯

来源:互联网 发布:mysql 去掉时分秒 编辑:程序博客网 时间:2024/05/22 08:23

实验一 进程与线程——Linux进程与线程通讯

一、实验目的

深刻理解线程和进程的概念,掌握线程与进程在组成成分上的差别,以及与其相适应的通讯方式和应用目标。

二、实验内容

1、以Linux系统进程和线程机制为背景,掌握fork()和clone()系统调用的形式和功能,以及与其相适应的高级通讯方式。由fork派生的子进程之间通过pipe通讯,由clone创建的线程之间通过共享内存通讯,对于后者需要考虑互斥问题。

2、以生产者/消费者问题为例,通过实验理解fork()和clone()两个系统调用的区别。程序要求能够创建4个进程或线程,其中包括两个生产者和两个消费者,生产者和消费者之间能够传递数据。

原书中代码 不再给出:遇到问题如下

1.书中有打印错误  CLONE_SIGNAND 应为 CLONE_SIGHAND

2.在mian中,创建线程的代码段;书中有错误;

int clone_flag,arg,retval;char *stack;03.clone_flag = CLONE_VM|CLONE_SIGNAND|CLONE_FS|CLONE_FILES;int i;for(i=0;i<2;i++){arg=i;stack=(char*)malloc(4096);retval = clone((void*)producer,&(stack[4095]),clone_flag,(void*)&arg);stack=(char*)malloc(4096);retval = clone((void*)consumer,&(stack[4095]),clone_flag,(void*)&arg);}


分析:
声明变量 *arg,在循环中 把 arg=i; 调用 clone时, 传入参数 &arg;

虽然 arg每次循环后 ,值不一样,但是 传入的参数&arg 即arg的地址没有变化,所以 作者原意 要创建两个 生产者和两个消费者的线程, 在实际运行会发现 结果只能创建出一个生产者和一个消费者。

修改后代码为:

int clone_flag,*arg, args[2] = {0, 1},retval;char *stack;clone_flag = CLONE_VM|CLONE_SIGHAND|CLONE_FS|CLONE_FILES;int i;for(i=0;i<2;i++){arg = &args[i];stack=(char*)malloc(4096);retval = clone((void*)producer,&(stack[4095]),clone_flag,(void*)arg);stack=(char*)malloc(4096);retval = clone((void*)consumer,&(stack[4095]),clone_flag,(void*)arg);}


完整代码如下:

#include "sched.h"#include "pthread.h"#include "stdio.h"#include "stdlib.h"#include "string.h"#include "semaphore.h" int producer(void *args);int consumer(void *args);pthread_mutex_t mutex;sem_t product;sem_t warehouse;char buffer[8][4];int bp=0;int main(int argc,char **argv){pthread_mutex_init(&mutex,NULL);sem_init(&product,0,0);sem_init(&warehouse,0,8);int clone_flag,*arg, args[2] = {0, 1},retval;char *stack;clone_flag = CLONE_VM|CLONE_SIGHAND|CLONE_FS|CLONE_FILES;int i;for(i=0;i<2;i++){arg = &args[i];stack=(char*)malloc(4096);retval = clone((void*)producer,&(stack[4095]),clone_flag,(void*)arg);stack=(char*)malloc(4096);retval = clone((void*)consumer,&(stack[4095]),clone_flag,(void*)arg);}exit(1);}int producer(void *args){int id=*((int*)args);int i;for(i=0;i<10;i++){sleep(i+1);sem_wait(&warehouse);pthread_mutex_lock(&mutex);if(id==0)strcpy(buffer[bp],"aaa\0");elsestrcpy(buffer[bp],"bbb\0");bp++;printf("producer %d produce %s in %d\n",id,buffer[bp-1],bp-1);pthread_mutex_unlock(&mutex);sem_post(&product);}printf("producer %d is over!\n",id);}int consumer(void *args){int id=*((int*)args);int i;for(i=0;i<10;i++){sleep(10-i);sem_wait(&product);pthread_mutex_lock(&mutex);bp--;printf("consumer %d get %s in %d\n",id,buffer[bp],bp);strcpy(buffer[bp],"zzz\0");pthread_mutex_unlock(&mutex);sem_post(&warehouse);}printf("consumer %d is over!\n",id);}


 

原创粉丝点击