【操作系统实验考试笔记】

题目

t1
利用fork pipe实现 cat /etc/passwd | wc -l 命令

//利用fork pipe实现 cat /etc/passwd | wc -l 命令

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <linux/string.h>
#include <fcntl.h>
int fd[2];
void mysys(char *cmd1,char *cmd2)
{
	char c1[100];
	char c2[100];
	strcpy(c1,cmd1);
	strcpy(c2,cmd2);
	pid_t pid;
   pipe(fd);
	/*创建子进程,管道的所有操作都在这里面完成*/
	pid=fork();
	if (pid == 0) { 
        // child
      //cat输出到屏幕的内容重定向到fd[1]管道写端
        dup2(fd[1], 1); 
        close(fd[0]);
        close(fd[1]);
       // execl("/bin/sh","sh","-c",cmd1 ,NULL);
       execlp("cat","cat","/etc/passwd",NULL);
        //write(1, "hello", 6); 
        exit(0);
    }
    // parent
   // int file=open("log.txt",O_CREAT|O_RDWR,666);
   
   //标准输入定向到管道输入端
   //wc直接到管道读端去读
    dup2(fd[0], 0); 
   //标准输入定向到管道输入端
   // dup2(file,1);
    close(fd[0]);
    close(fd[1]);
    execlp("wc","wc","-l",NULL);
    //read(0, buf, sizeof(buf)); 
    //execl("/bin/sh","sh","-c",cmd2 ,NULL);
    //printf("Receive:%s\n", buf); 
    //return 0;

	
}

 
int main()
{
	printf("> ");
	char command[100];
	 /*分割两条命令,分别存入cmd1,和cmd2中。
	 以 | 为分隔符,将命令以及参数字符串存入*/
	fgets(command,100,stdin);
	char *cmd1,*cmd2,*filename;
	cmd1= strtok(command," ");
    // puts(cmd1);
	filename= strtok(NULL,"|");
	//puts(filename);
	cmd2= strtok(NULL,"\n");
	//puts(cmd2);
	
	//创建新数组地址
	char *command1= (char *)malloc(strlen(cmd1)+strlen(filename)+1);
	char *command2= (char *)malloc(strlen(cmd2)+strlen(filename)+1);
	strcpy(command1,cmd1);
	strcat(command1," ");
	strcat(command1,filename);
	//puts(command1);
	strcpy(command2,cmd2);
  // puts(command2);
   mysys(command1,command2);
	
	return 0;
}

2019 t2

10个子进程计算0100之,和第一个进程计算010,第二计算11~20,以此类推。 并利用管道把结果返回到主进程

//10个子进程计算0~100,第一个进程计算0~10,第二计算11~20,以此类推。 并利用管道把结果返回到主进程
//(open函数)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//(read/write)(pipe) (sleep)
#include <unistd.h>
//(进程)
#include <stdio.h>
//(exit)
#include <stdlib.h>
//pthread.h包含了函数pthread_create的声明
#include <pthread.h>
int main()
{
    int pid;    
    int allsum=0;
    int fds[20];
    int i;
    for(i=0;i<20;i++)
       {
           
           pipe(&fds[i*2]);
       }

     for( i=0;i<10;i++)
     {

        pid = fork();
       if (pid == 0) 
       { 
            int j=0;
            int sum=0;
            for(j=(i*10+1);j<=(i+1)*10;j++)
                sum+=j;

            write(fds[i*2+1], &sum,sizeof(int));
            for(i=0;i<20;i++)
             close(fds[i]);
         exit(0);
       }

     }
     
     
  
    
    
    // parent

    for (i = 0; i < 10; i++) {
        int result=0;
        read(fds[i*2],&result,sizeof(int));
        allsum += result;
    }
     for( i =0; i<20;i++)
        close(fds[i]);

    printf("sum = %d\n", allsum);

    return 0;
}

2019 t3

2个线程计算1100,第一个计算startmiddle,第二个计算middle~end。

#include <stdio.h>
#include <pthread.h>
#include <pthread.h>
#include <sys/types.h>
#include <stdlib.h>

struct params
{
    int start;
    int end;
};

struct result
{
   int sum;
 };

 void *compute(void *args)
 {
     struct params *param=(struct params*)args;
     int sum=0;
     int i;
     for(i=param->start;i<=param->end;i++)
         sum+=i;
     
     struct result *result=malloc(sizeof(struct result));
     result->sum=sum;
     return result;
     }

int parallel_add(int start, int end)
{
    int middle=(start+end)/2;
    struct params param[2];
    pthread_t worker[2];
    int sum=0;
    int i=0;
    struct result *result;
    struct params *p_param=param;
    p_param->start=start;
    p_param->end=middle;
    pthread_create(&worker[0],NULL,compute,p_param);
    p_param++;
    p_param->start=middle+1;
    p_param->end=end;
    pthread_create(&worker[1],NULL,compute,p_param);
    for(i=0;i<2;i++)
    
    {
        
        pthread_join(worker[i],(void**)&result);
        sum+=result->sum;
        free(result);
     }
     return sum;


}

int main()
{
    // 1+2+3 ... + 100 = 5050
    printf("sum = %d\n", parallel_add(1, 101));
    return 0;
}

2019 t4

4个子进程,分别为爹妈儿女。爹往盘子里放苹果,儿子消耗苹果。妈往盘子里放橘子,女儿消耗橘子。盘子里只容许放一个水果。
使程序按如下结果运行循环
put apple
get apple
put orange
get orange

#include <stdio.h>
#include <pthread.h>
int temp=0;
pthread_mutex_t mutex;
pthread_cond_t wait_apple;
pthread_cond_t wait_orange;
pthread_cond_t full_apple;
pthread_cond_t full_orange;
void *father_entry(void *arg)
{
   while(1)
{   pthread_mutex_lock(&mutex);
    while(temp!=0)
        pthread_cond_wait(&wait_orange,&mutex);
    temp=1;
    puts("put apple");
    pthread_cond_broadcast(&full_apple);
    pthread_mutex_unlock(&mutex);
    sleep(1);
}
    return NULL;
}

void *mother_entry(void *arg)
{
    while(1)
    {
    pthread_mutex_lock(&mutex);
    while(temp!=0)
        pthread_cond_wait(&wait_apple,&mutex);
    temp=2;
    puts("put orange");
    pthread_cond_broadcast(&full_orange);
    pthread_mutex_unlock(&mutex);
    sleep(1);
    }
    return NULL;
}

void *son_entry(void *arg)
{
    while(1)
    {
    pthread_mutex_lock(&mutex);
    while(temp!=1)
        pthread_cond_wait(&full_apple,&mutex);

    temp=0;    
    puts("get apple");
    pthread_cond_broadcast(&wait_apple);
    pthread_mutex_unlock(&mutex);
    sleep(1);
    }
    return NULL;
}

void *daughter_entry(void *arg)
{
   while(1){
   pthread_mutex_lock(&mutex);
    while(temp!=2)
        pthread_cond_wait(&full_orange,&mutex);
    temp=0;
    puts("get orange");
    pthread_cond_broadcast(&wait_orange);
    pthread_mutex_unlock(&mutex);
    sleep(1);
   }
    return NULL;
}

int main()
{
    pthread_t father_thread;
    pthread_t mother_thread;
    pthread_t son_thread;
    pthread_t daughter_thread;
    pthread_mutex_init(&mutex,NULL);
    pthread_cond_init(&wait_apple,NULL);
    pthread_cond_init(&wait_orange,NULL);
    pthread_cond_init(&full_apple,NULL);
    pthread_cond_init(&full_orange,NULL);
    temp=0;
    pthread_create(&father_thread, NULL, &father_entry, NULL);
    sleep(1);
    pthread_create(&mother_thread, NULL, &mother_entry, NULL);
    pthread_create(&son_thread, NULL, &son_entry, NULL);
    pthread_create(&daughter_thread, NULL, &daughter_entry, NULL);

    while (1);
    return 0;
}

2016 t1

主进程创建1个子进程
主进程通过管道与子进程连接
子进程的标准输出连接到管道的写端
主进程的标准输入连接到管道的读端
在子进程中调用exec(“echo”, “echo”, “hello world”, NULL)
在父进程中调用read(0, buf, sizeof(buf)),从标准输入中获取子进程发送的字符串,并打印出来

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
    int fds[2];
    int buf[512];
    pipe(fds); 
    pid_t pid;
    pid = fork();
    int readsize;
    if(pid == 0)
    {
        dup2(fds[1],STDOUT_FILENO);
        execlp("echo", "echo", "hello world", NULL);
        exit(0);
    }
    else if (pid > 0)
    {
     	readsize = read(fds[0], buf, 512);
     	write(STDOUT_FILENO, buf, readsize);      
    }
    close(fds[0]);
    close(fds[1]);
    return 0;

}

2016 t2

主进程创建2个子进程,主进程通过两个管道分别与两个子进程连接
第一个子进程计算从1加到50的和,并将结果通过管道送给父进程
第一个子进程计算从50加到100的和,并将结果通过管道送给父进程
父进程读取两个子进程的结果,将他们相加,打印出来,结果为5050


2016 t3

1.主线程创建10个子线程 - 第0个子线程计算从01加到10的和 - 第1个子线程计算从11加到20的和 - 第2个子线程计算从21加到30的和 - … - 第9个子线程计算从91加到100的和 2. 主线程归并10个子线程的计算结果,最终结果为5050 3. 本题必须使用线程参数来完成

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>


typedef struct {
    int from;
    int to;
    int ans;
} Arg;


void *calc(void *arg)
{
    Arg *p = arg;
    int i;
    p->ans = 0;
    for(i = p->from; i<= p->to; ++i)
    	p->ans += i;
    return NULL;
}

int main(void)
{
    pthread_t ths[10];
    Arg args[10];
    int i, sum=0;    
    for(i = 0; i< 10; ++i)
    {
    	args[i].from = i*10 + 1;
    	args[i].to = (i+1) * 10;
    	pthread_create(ths + i, 0, calc, args + i); 
    }
    
    for(i = 0; i< 10; ++i)
        pthread_join(ths[i], NULL);
    
    for(i = 0; i<10; ++i)
        sum += args[i].ans;
    
    printf("%d\n", sum);    
    return 0;
}

2016 t4

  1. 主线程创建4个子线程T1、T2、T3、T4,主线程在4个子线程退出后,才退出
  2. 线程T1、T2、T3、T4的运行时代码如下:
#include <unistd.h> // sleep函数声明在该头文件中

void *T1_entry(void *arg)
{
    sleep(2);  // 睡眠2秒,不准删除此条语句,否则答题无效
    puts(“T1”);
}

void *T2_entry(void *arg)
{
    sleep(1);  // 睡眠1秒,不准删除此条语句,否则答题无效
    puts(“T2”);
}

void *T3_entry(void *arg)
{
    sleep(1);  // 睡眠1秒,不准删除此条语句,否则答题无效
    puts(“T3”);
}

void *T4_entry(void *arg)
{
    puts(“T4”);
}
  1. 使用信号量或者条件变量机制(而不是使用sleep函数),使得这四个线程满足如下制约关系:
    • T1的print语句执行后,T2和T3才可以执行print语句
    • T2和T3的print语句执行后,T4才可以执行print语句
  2. 程序输出结果为
T1
T2
T3
T4

或者

T1
T3
T2
T4
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

pthread_cond_t s1_signal = PTHREAD_COND_INITIALIZER;
pthread_cond_t s2_signal = PTHREAD_COND_INITIALIZER;
int t1_gone = 0, t2_gone = 0, t3_gone = 0;
pthread_mutex_t s1_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t s2_mutex = PTHREAD_MUTEX_INITIALIZER;

void *T1_entry(void *arg)
{
    pthread_mutex_lock(&s1_mutex);

    sleep(2);
    puts("T1");

    t1_gone = 1;
    pthread_cond_broadcast(&s1_signal);
    pthread_mutex_unlock(&s1_mutex);

    return NULL;
}

void *T2_entry(void *arg)
{
    pthread_mutex_lock(&s1_mutex);
    while(!t1_gone)
        pthread_cond_wait(&s1_signal, &s1_mutex);
    pthread_mutex_unlock(&s1_mutex);
    
    sleep(1);
    puts("T2");
    
    pthread_mutex_lock(&s2_mutex);
    t2_gone = 1;
    pthread_cond_signal(&s2_signal);
    pthread_mutex_unlock(&s2_mutex);
    
    return NULL;
}

void *T3_entry(void *arg)
{
    pthread_mutex_lock(&s1_mutex);
    while(!t1_gone)
        pthread_cond_wait(&s1_signal, &s1_mutex);
    pthread_mutex_unlock(&s1_mutex);
     
    sleep(1);
    puts("T3");
    
    pthread_mutex_lock(&s2_mutex);
    t3_gone = 1;
    pthread_cond_signal(&s2_signal);
    pthread_mutex_unlock(&s2_mutex);

    return NULL;
}

void *T4_entry(void *arg)
{
    pthread_mutex_lock(&s2_mutex);
    while(!t2_gone || !t3_gone)
        pthread_cond_wait(&s2_signal, &s2_mutex);
        
    puts("T4");
    
    pthread_mutex_unlock(&s2_mutex);
    return NULL;
}



int main(void)
{
    pthread_t t1,t2,t3,t4;
    pthread_create(&t1, 0, T1_entry, NULL);
    pthread_create(&t2, 0, T2_entry, NULL);
    pthread_create(&t3, 0, T3_entry, NULL);
    pthread_create(&t4, 0, T4_entry, NULL);
    
    pthread_join(t4, NULL);
    return 0;
}

第二种

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

typedef struct {
	int value;
	pthread_mutex_t mutex;
	pthread_cond_t cond;
}sema_t;

sema_t t1_2_ready;
sema_t t1_3_ready;
sema_t t2_ready;
sema_t t3_ready;


void sema_init(sema_t *sema, int value)
{
	sema->value = value;
	pthread_mutex_init(&sema->mutex, NULL);
	pthread_cond_init(&sema->cond, NULL);
}

void sema_wait(sema_t *sema)
{
	pthread_mutex_lock(&sema->mutex);
	while (sema->value <= 0)
        	pthread_cond_wait(&sema->cond, &sema->mutex);
    	sema->value--;
	pthread_mutex_unlock(&sema->mutex);
}

void sema_signal(sema_t *sema)
{
	pthread_mutex_lock(&sema->mutex);
	++sema->value;
	pthread_cond_signal(&sema->cond);
	pthread_mutex_unlock(&sema->mutex);
}

void *T1_entry(void *arg)
{
	sleep(2);  // 睡眠2秒,不准删除此条语句,否则答题无效
	puts("T1");
	sema_signal(&t1_2_ready);
	sema_signal(&t1_3_ready);

}

void *T2_entry(void *arg)
{
	sema_wait(&t1_2_ready);
	sleep(1);  // 睡眠1秒,不准删除此条语句,否则答题无效
	puts("T2");
	sema_signal(&t2_ready);
}

void *T3_entry(void *arg)
{
	sema_wait(&t1_3_ready);
	sleep(1);  // 睡眠1秒,不准删除此条语句,否则答题无效
	puts("T3");
	sema_signal(&t3_ready);

}

void *T4_entry(void *arg)
{
	sema_wait(&t2_ready);
	sema_wait(&t3_ready);
	puts("T4");
}

int main()
{
	sema_init(&t1_2_ready,0);
	sema_init(&t1_3_ready,0);
	sema_init(&t2_ready,0);
	sema_init(&t3_ready,0);

	pthread_t T1,T2,T3,T4;
	pthread_create(&T1, NULL, T1_entry, NULL);
	pthread_create(&T2, NULL, T2_entry, NULL);
	pthread_create(&T3, NULL, T3_entry, NULL);
	pthread_create(&T4, NULL, T4_entry, NULL);
	pthread_join(T1,NULL);
	pthread_join(T2,NULL);
	pthread_join(T3,NULL);
	pthread_join(T4,NULL);
	return 0;
}

ring.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define N 10
#define LOOPCOUNT 25

void *add(void *arg){
    int *num = (int *)arg;
    num[1] = num[0] + 1;
    int *result = num;
}
int main()
{
    int buff[N][2];
    int i = 0;
    for(i = 0;i < N;i++)
    {
        buff[i][0]=0;
        buff[i][1]=0;
    }
    pthread_t tids[N];

    i = 0;
    int count = 0;
    while(i < N)
    {
        count++;
        if(count == LOOPCOUNT)
            break;

        printf("from T[%d]",i+1);
        pthread_create(&tids[i],NULL,add,(void *)&buff[i]);
        pthread_join(tids[i],NULL);
        int result = buff[i][1];

        i = (i+1) % N;
        buff[i][0] = result;
        printf("to T[%d] send %d\n",i+1,result);
    }
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值