操作系统实验-进程

1、 实验目的

熟悉Linux下进程管理和相关的系统调用。

2、 实验内容

(1). Linux 下用线程模拟实现“生产-消费者”或“读者-写者”或“哲学家就餐”同步问题。

将设计分析过程和源代码写入实验报告。

(2). 补缺三段代码,并回答问题。

将设计分析过程和源代码写入实验报告。

3、实验代码

(1) 进程

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
/* 允许建立的子进程个数最大值 */
#define MAX_CHILD_NUMBER    10
/* 子进程睡眠时间 */
#define SLEEP_INTERVAL        2
int proc_number=0; /* 子进程的自编号,从0开始 */
void do_something();
int main(int argc, char* argv[])
{
    int child_proc_number = MAX_CHILD_NUMBER;    /* 子进程个数 */
    int i, ch;
    pid_t child_pid;
    pid_t pid[10]={0};    /* 存放每个子进程的id */
    
    if (argc > 1)
    {
        /* 命令行参数中的第一个参数表示建立几个子进程,最多10个 */
        child_proc_number = atoi(argv[1]);
        child_proc_number 
            = (child_proc_number > 10) ? 10 : child_proc_number; 
    }
    for (i=0; i<child_proc_number; i++)
        {
        child_pid = fork();
        if(child_pid > 0)
        {
            pid[i] = child_pid; 
        
        }
        else if(child_pid == 0)
        {
            proc_number = i;
            do_something();
        }
        else
        {
            perror("fail to fork!\n"); 
        }
       
        /* 在这里填写代码,建立child_proc_number个子进程
        * 子进程要执行
        *    proc_number = i;
        *    do_something();
        * 父进程把子进程的id保存到pid[i] */
    }
    
    /* 让用户选择杀死哪个进程。输入数字(自编号)表示杀死该进程
    * 输入q退出 */
    while ((ch = getchar()) != 'q')
    {
        if (isdigit(ch))
        {
            kill(pid[ch-'0'], SIGTERM);
            /* 在这里填写代码,向pid[ch-'0']发信号SIGTERM,
            * 杀死该子进程 */
        }
        
    }
/* 在这里填写代码,杀死本组的所有进程 */
    kill(0, SIGTERM);
    return 0;    
    
    
}
void do_something()
{
    for(;;)
    {
        printf("This is process No.%d and its pid is %d\n",  proc_number,  getpid());
        sleep(2); /* 主动阻塞两秒钟 */
    }
}

(2)线程

/*  POSIX 下线程控制的实验程序残缺版 */ 
#include <stdio.h> 
#include <sys/types.h>
#include <unistd.h> 
#include <ctype.h>
#include <pthread.h> 
#include<stdlib.h>
#include<semaphore.h>

#define MAX_THREAD 3 /* 线程的个数 */
unsigned long long main_counter, counter[MAX_THREAD]; /* unsigned long  long是比long还长的整数 */
//sem_t S1;
void* thread_worker(void*); 

int main(int argc, char* argv[])
{ 
      int i, rtn, ch; 
      pthread_t pthread_id[MAX_THREAD] = {0}; /* 存放线程id*/    
       //sem_init(&S1,0,1);
      for (i=0; i<MAX_THREAD; i++)    { 
         /* 在这里填写代码,用pthread_create建一个普通的线程, 
           线程id存入pthread_id[i],线程执行函数是thread_worker
           并i作为参数传递给线程 */
           // if(pthread_create(&pthread_id[i], NULL, thread_worker, &i)!=0){
	  if(pthread_create(&pthread_id[i], NULL, thread_worker, (void *)i)!=0){
                      printf("thread_create failed");    
		       exit(1);    
	    }
     } 
     do {/* 用户按一次回车执行下面的循环体一次。按q退出 */ 
           unsigned long long sum = 0;/* 求所有线程的counter的和 */
       for (i=0; i<MAX_THREAD; i++)  {/* 求所有counter的和 */
              sum += counter[i]; 
              printf("counter[%d]=%llu  ", i,counter[i]); 
         }
        printf("%llu/%llu", main_counter, sum);   
     }  while ((ch = getchar()) != 'q'); 
	//sem_destroy(&S1);
   return  0;
} 
void* thread_worker(void* p) { 
     int thread_num;  
    /* 在这里填写代码,把main中的i的值传递给thread_num */ 
     //thread_num = *(int*)p;
        thread_num = (int)(p);
    for(;;) { /* 无限循环 */
           counter[thread_num]++; /* 本线程的counter加一 */ 
           //sem_wait(&S1);
	   main_counter++; /* 主counter 加一 */
	   //sem_post(&S1);
     } 
}

(3)互斥

//* POSIX 下线程死锁的演示程序 */ 
#include <stdio.h> 
#include <sys/types.h>
#include <unistd.h> 
#include <ctype.h>
#include <pthread.h> 
#define LOOP_TIMES 10000 
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;   /*用宏PTHREAD_MUTEX_INITIALIZER来初始化 */
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void* thread_worker(void*);
void critical_section(int thread_num, int i);  
int main(void)  { 
      int rtn, i; 
      pthread_t pthread_id = 0; /* 存放子线程的id */ 
      rtn = pthread_create(&pthread_id,   NULL, thread_worker, NULL ); 
      if(rtn != 0) { 
            printf("pthread_create ERROR!\n"); 
            return -1; 
      } 
      for (i=0; i<LOOP_TIMES; i++)  { 
        pthread_mutex_lock(&mutex1);
	pthread_mutex_lock(&mutex2); 
	critical_section(1, i); 
	pthread_mutex_unlock(&mutex2);
	pthread_mutex_unlock(&mutex1);
      } 
     pthread_mutex_destroy(&mutex1);
     pthread_mutex_destroy(&mutex2); 
     return 0; 
} 
void* thread_worker(void* p)  { 
      int i; 
      for (i=0; i<LOOP_TIMES; i++) { 
       // pthread_mutex_lock(&mutex2);
	//pthread_mutex_lock(&mutex1); 
        pthread_mutex_lock(&mutex1);
	pthread_mutex_lock(&mutex2); 
	critical_section(2, i); 
	pthread_mutex_unlock(&mutex2);
	pthread_mutex_unlock(&mutex1);
      }
} 
void critical_section(int thread_num, int i) { 
      printf("Thread%d: %d\n", thread_num,  i);
}

(4)模拟生产者-消费者

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
  
#define M 10 

int in = 0;  
int out = 0; 

int buff[M] = {0}; 

sem_t empty_sem;
sem_t full_sem;  
pthread_mutex_t mutex;

int producer = 0;  
int consumer = 0; 


void print()
{
int i;
for(i = 0; i < M; i++)
   printf("%d ", buff[i]);
printf("\n");
}


void *product()
{
while(1)
{
   
   sleep(1);
   
   sem_wait(&empty_sem);
   pthread_mutex_lock(&mutex);
  
   in = in % M;
   printf("producer at %d position: \t",  in);
  
   buff[in] = 1;  
   print();  
   ++in;
  
   pthread_mutex_unlock(&mutex);
   sem_post(&full_sem);  
}
}
void *prochase()
{
while(1)
{
  
   sleep(2);
   sem_wait(&full_sem);
   pthread_mutex_lock(&mutex);
  
   out = out % M;
   printf("consumer at %d position: \t",  out);
  
   buff[out] = 0;
   print();
   ++out;
  
   pthread_mutex_unlock(&mutex);
   sem_post(&empty_sem);
}
}

int main()
{
pthread_t id1;
pthread_t id2;
int ret;

int ini1 = sem_init(&empty_sem, 0, M); 
int ini2 = sem_init(&full_sem, 0, 0);  
if(ini1 && ini2 != 0)
{
   printf("sem init failed \n");
   exit(1);
} 

int ini3 = pthread_mutex_init(&mutex, NULL);
if(ini3 != 0)
{
   printf("mutex init failed \n");
   exit(1);
} 
    
   ret = pthread_create(&id1, NULL, product,NULL);//
   if(ret != 0)
   {
    printf("product creation failed \n");
    exit(1);
   }

   ret = pthread_create(&id2, NULL, prochase, NULL);
   if(ret!= 0)
   {
    printf("prochase creation failed \n");
    exit(1);
   }


   pthread_join(id1,NULL);
   pthread_join(id2,NULL);


exit(0); 
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值