头歌课堂练习5:进程的同步与互斥

第一关 多线程编程

//创建多线程的函数pthread_create原型如下:
pthread_create(pthread_t *tidp, const pthread_attr_t *attr,
    (void*)(*start_rtn)(void*), void *arg);

*tidppthread_t类型,也就是指向线程标识符的指针
通俗来讲,要开一个新线程,
那么就得新定义一个pthread_t类型的指针。

*arrtpthread_arrt_t类型
说的是用来设置线程属性,我还没怎么接触这个
一般用NULL

*strat_rtn 是这里 (void*)(*hh)(void*)类型
是线程运行函数的起始地址
虽然上面说的很复杂,但说简单点,就是得
这样命名 void *p(); 就可以用了

*arg 最后一个参数是运行函数的参数。
很简单

pthread_join();

如果主线程结束时,子线程还没有结束,那么子线程会被操作系统杀死。可以在主线程中使用 pthread_join 来等待子线程结束。

关于题目:把一个有两个进程的改成三个进程
原题目:

#include 
#include 
#include 

int sum1 = 0, sum2 = 0;

void *p1(){
  int i, tmp = 0;
  for (i = 1; i <= 100; i++)
    tmp += i;
  sum1 += tmp;
}

void *p2(){
  int i, tmp = 0;
  for (i = 101; i <= 200; i++)
    tmp += i;
  sum2 += tmp;
}

void p3(){
  printf("sum: %d\n", sum1 + sum2);
}

int main(){
  int res;
  pthread_t t;
  void *thread_result;
  res = pthread_create(&t, NULL, p1, NULL);
  if (res != 0){
    perror("failed to create thread");
    exit(1);
  }
  p2();
  res = pthread_join(t, &thread_result);
  if (res != 0){
    perror("failed to join thread");
    exit(2);
  }
  p3();
  return 0;
}

改后如下:

#include 
#include 
#include 

int sum1 = 0, sum2 = 0;

void *p1(){
  int i, tmp = 0;
  for (i = 1; i <= 100; i++)
    tmp += i;
  sum1 += tmp;
}

void *p2(){
  int i, tmp = 0;
  for (i = 101; i <= 200; i++)
    tmp += i;
  sum2 += tmp;
}

void p3(){
  printf("sum: %d\n", sum1 + sum2);
}

int main(){
  int res;
  pthread_t t1;
  pthread_t t2; //像这里,就是开一个新线程
  void *thread_result;
  res = pthread_create(&t1, NULL, p1, NULL);
  if (res != 0){
    perror("failed to create thread");
    exit(1);
  }
  res = pthread_create(&t2, NULL, p2, NULL);
  //在这里,加一个线程,就是开一个新的。
  if (res != 0){
    perror("failed to join thread");
    exit(2);
  }
  res = pthread_join(t1, &thread_result);
  res = pthread_join(t2, &thread_result);
  //这里再加这个
  p3();
  return 0;
}

最后总结:是学的云里雾里,最后查网络上
main函数也是一个进程
先用pthread_t 新定义一个新的指针,再
void *thread_result;我也不知道这个具体的什么,反正后面要用到
pthread(指针, NULL, 函数, NULL) 创建一个新进程
在最后
pthread_join(t,&thread_result);
然后完成。

第二关

程序 4.c 模拟了如下场景:某休息厅里有足够多(10 把以上)的椅子,10 位顾客先后进入休息厅寻找空椅子,找到后开始在椅子上休息,休息完后让出空椅子、退出休息厅。请只在该程序中插入一些代码(不删除现有代码),来将上述场景调整为休息厅里只有 2 把椅子。
这个题简单,
以下直接来答案:
头歌课堂练习5:进程的同步与互斥_第1张图片

源代码如下:

#include 
#include 
#include 
#include 
#include 
#include 

#define CUSTOMER_NUM  2

int customer_state[CUSTOMER_NUM] = {0};

void sleep_random(int t) {
  sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}

void print_cur_state() {
  int i;
  printf("  customers with seats: (");
  for (i = 0; i < CUSTOMER_NUM; i++)
  {
    if (0 != customer_state[i])
      printf(" %d", i+1);
  }
  printf(" )\n");
}

void *customer(void *id)
{
  const int myid = *(int*)id;
  sleep_random(2);
  printf("customer %d: try to get a seat...\n", myid);

  printf("customer %d: sit down\n", myid);
  customer_state[myid-1] = 1;
  print_cur_state();

  sleep_random(3);

  printf("customer %d: stand up\n", myid);
  customer_state[myid-1] = 0;
  print_cur_state();
}

int main()
{
  int i, id[CUSTOMER_NUM], res;
  pthread_t t[CUSTOMER_NUM];

  srand((int)time(0));

  for (i = 0; i < CUSTOMER_NUM; i++)
  {
    id[i] = i + 1;
    pthread_create(&t[i], NULL, customer, &id[i]);
  }
  for (i = 0; i < CUSTOMER_NUM; i++)
  {
    res = pthread_join(t[i], NULL);
    if (res != 0){
      perror("failed to join thread");
      exit(2);
    }
  }
  return 0;
}

第三关

程序 9.c 实现了哲学家就餐问题,里面存在死锁问题,请用资源顺序分配法改写该程序,避免死锁。

待加入:

#include 
#include 
#include 
#include 
#include 
#include 

void sleep_random(int t) {
  sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}

void delay(){
  int i = 10000000;
  while (i--)
    ;
}

#define N  5
sem_t chopstick[N];

void *phi(void *id){  /* 'id' starts from 1 */
  int i, left, right, myid = *(int*)id;
  left = myid - 1;
  right = (myid < N) ? myid : 0;
  for (i = 0; i < 3; i++){
    printf("phi #%d: start of thinking\n", myid);
/**** start *************/

      sem_wait(&chopstick[left]);
      delay();
      sem_wait(&chopstick[right]);

/**** end ***************/
    printf("phi #%d: start of eating\n", myid);
    sleep_random(3);
    sem_post(&chopstick[left]);
    sem_post(&chopstick[right]);
    printf("phi #%d: end of eating\n", myid);
  }
}

int main(){
  int i, id[N];
  pthread_t t[N];
  srand((int)time(0));
  for (i = 0; i < N; i++){
    id[i] = i + 1;
    sem_init(&chopstick[i], 0, 1);
  }
  for (i = 0; i < N; i++)
    pthread_create(&t[i], NULL, phi, &id[i]);
  for (i = 0; i < N; i++)
    pthread_join(t[i], NULL);
  return 0;
}

其实很简单,有一种避免什么死循环的意思
加点条件束缚住。。。

/* start */
    if(left

你可能感兴趣的:(头头操作系统做题记录,linux)