昆哥吧 关注:15贴子:242
  • 10回复贴,共1

实验六(实验指导书)

收藏回复

  • 61.157.97.*
实验六 线程
33.3.6.1 实验类型与学时安排
题目一 验证型实验,1学时
题目二 设计型实验  3学时
34.3.6.2 实验目的
1、掌握线程的创建,取消,同步函数的使用
2、掌握互斥锁,条件变量的使用
35.3..6.3 实验知识
创建线程
int  pthread_create(pthread_t  * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg)
与fork()调用创建一个进程的方法不同,pthread_create()创建的线程并不具备与主线程(即调用pthread_create()的线程)同样的执行序列,而是使其运行start_routine(arg)函数。
第一个参数为指向线程标识符的指针,
第二个参数用来设置线程属性,
第三个参数是线程运行函数的起始地址,
最后一个参数是运行函数的参数。


1楼2007-10-29 08:27回复
    • 61.157.97.*
    线程取消的方法是向目标线程发Cancel信号,但如何处理Cancel信号则由目标线程自己决定,或者忽略、或者立即终止、或者继续运行至Cancelation-point(取消点),由不同的Cancelation状态决定。线程接收到CANCEL信号的缺省处理(即pthread_create()创建线程的缺省状态)是继续运行至取消点,也就是说设置一个CANCELED状态,线程继续运行,只有运行至Cancelation-point的时候才会退出。
    取消点
    根据POSIX标准,pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及read()、write()等会引起阻塞的系统调用都是Cancelation-point,而其他pthread函数都不会引起Cancelation动作。


    3楼2007-10-29 08:29
    回复
      • 61.157.97.*
      但是pthread_cancel的手册页声称,由于LinuxThread库与C库结合得不好,因而目前C库函数都不是Cancelation-point;但CANCEL信号会使线程从阻塞的系统调用中退出,并置EINTR错误码,因此可以在需要作为Cancelation-point的系统调用前后调用pthread_testcancel(),从而达到POSIX标准所要求的目标,即如下代码段:
      pthread_testcancel();
       retcode = read(fd, buffer, length);
       pthread_testcancel();
      与线程取消相关的pthread函数
      int pthread_cancel(pthread_t thread)
      发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。


      4楼2007-10-29 08:30
      回复
        • 61.157.97.*
        int pthread_setcancelstate(int state, int *oldstate)
        设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和PTHREAD_CANCEL_DISABLE,分别表示收到信号后设为CANCLED状态和忽略CANCEL信号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。

        int pthread_setcanceltype(int type, int *oldtype)
        设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFFERED和PTHREAD_CANCEL_ASYCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到信号后继续运行至下一个取消点再退出和立即执行取消动作(退出);oldtype如果不为NULL则存入运来的取消动作类型值。
        void pthread_testcancel(void)
        检查本线程是否处于Canceld状态,如果是,则进行取消动作,否则直接返回。


        5楼2007-10-29 08:31
        回复
          • 61.157.97.*
          线程同步
          互斥锁的相关函数
          pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
          pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
          pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
          以上是静态初始化信号量。

          int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex-attr_t *mutexattr);//动态出世化信号量
          int pthread_mutex_lock(pthread_mutex_t *mutex);//加锁
          int pthread_mutex_trylock(pthread_mutex_t *mutex);//测试加锁,如果忙返回EBUSY int pthread_mutex_unlock(pthread_mutex_t *mutex);//解锁
          int pthread_mutex_destroy(pthread_mutex_t *mutex);//摧毁信号灯。


          6楼2007-10-29 08:31
          回复
            • 61.157.97.*
            条件变量
            条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。一般说来,条件变量被用来进行线承间的同步。
            条件变量的结构为pthread_cond_t,函数pthread_cond_init()被用来初始化一个条件变量。它的原型为:
            extern int pthread_cond_init __P ((pthread_cond_t *__cond,__const pthread_condattr_t *__cond_attr));


            7楼2007-10-29 08:32
            回复
              • 61.157.97.*
              其中cond是一个指向结构pthread_cond_t的指针,cond_attr是一个指向结构pthread_condattr_t的指针。结构pthread_condattr_t是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用。注意初始化条件变量只有未被使用时才能重新初始化或被释放。释放一个条件变量的函数为pthread_cond_ destroy(pthread_cond_t cond)。 
              函数pthread_cond_wait()使线程阻塞在一个条件变量上。它的函数原型为:
              extern int pthread_cond_wait __P ((pthread_cond_t *__cond,pthread_mutex_t *__mutex));


              8楼2007-10-29 08:33
              回复
                • 61.157.97.*
                线程解开mutex指向的锁并被条件变量cond阻塞。线程可以被函数pthread_cond_signal和函数pthread_cond_broadcast唤醒,但是要注意的是,条件变量只是起阻塞和唤醒线程的作用,具体的判断条件还需用户给出,线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。

                另一个用来阻塞线程的函数是pthread_cond_timedwait(),它的原型为:
                extern int pthread_cond_timedwait __P ((pthread_cond_t *__cond,pthread_mutex_t *__mutex, __const struct timespec *__abstime));


                9楼2007-10-29 08:34
                回复
                  • 61.157.97.*
                  它比函数pthread_cond_wait()多了一个时间参数,经历abstime段时间后,即使条件变量不满足,阻塞也被解除。
                  函数pthread_cond_signal()的原型为:
                  extern int pthread_cond_signal __P ((pthread_cond_t *__cond));
                  它用来释放被阻塞在条件变量cond上的一个线程。多个线程阻塞在此条件变量上时,哪一个线程被唤醒是由线程的调度策略所决定的。


                  10楼2007-10-29 08:35
                  回复
                    • 61.157.97.*
                    36.3.6.4 实验内容
                    题目一:编译调试运行下面的程序,并回答问题。
                    /* example.c*/
                    #include <stdio.h>
                    #include <pthread.h>
                    void thread(void)
                    {
                     int i;
                     for(i=0;i<3;i++)
                     printf("This is a pthread\n");
                    }

                    int main(void)
                    {
                     pthread_t id;
                     int i,ret;
                     ret=pthread_create(&id,NULL,(void *) thread,NULL);
                     if(ret!=0)
                    {
                       printf ("Create pthread error!n");
                     exit (1);
                    }
                    for(i=0;i<3;i++)
                      printf("This is the main process\n");
                     pthread_join(id,NULL);
                     return (0);
                    }
                    问题:多次运行该程序,输出结果是否一样?为什么?

                    题目二:利用互斥锁和条件变量编程解决生产者-消费者问题。
                    实验提示:参见《操作系统原理》中的算法实现


                    11楼2007-10-29 08:36
                    回复
                      • 61.157.97.*
                      .


                      12楼2007-10-29 08:37
                      回复