Presentation is loading. Please wait.

Presentation is loading. Please wait.

实验二 Linux 线程及信号灯 一、目的 了解并掌握 Linux 线程及信号灯。 二、要求 1 、了解 Linux 线程与信号灯使用: ( 1 ) Linux 线程 ( 2 ) Linux 信号灯 ( 3 )线程互斥 ( 4 )线程同步.

Similar presentations


Presentation on theme: "实验二 Linux 线程及信号灯 一、目的 了解并掌握 Linux 线程及信号灯。 二、要求 1 、了解 Linux 线程与信号灯使用: ( 1 ) Linux 线程 ( 2 ) Linux 信号灯 ( 3 )线程互斥 ( 4 )线程同步."— Presentation transcript:

1 实验二 Linux 线程及信号灯 一、目的 了解并掌握 Linux 线程及信号灯。 二、要求 1 、了解 Linux 线程与信号灯使用: ( 1 ) Linux 线程 ( 2 ) Linux 信号灯 ( 3 )线程互斥 ( 4 )线程同步

2 三、内容 1 、熟悉 Linux 线程接口及连接; 2 、了解 Linux 信号灯的编程; 3 、编程模拟实现飞机售票; 创建多个售票线程; 已售票使用公用全局变量; 创建互斥信号灯; 对售票线程临界区施加 P 、 V 操作。

3 4 、编程模拟实现双线程单缓冲 区的合作; 创建多个计算线程与输出线程; 创建同步信号灯; 缓冲区用全局公用数组变量; 对计算线程与输出线程施加 P 、 V 操作。

4 四、预备知识 1 、线程接口 线程创建 int pthread_create __P ((pthread_t *__thread, __const pthread_attr_t *__attr, void *(*__start_routine) (void *), void *__arg)); 参数: __thread 指向返回线程标识符的指针 ; __attr 设置线程属性 ; __start_routine 线程运行函数地址 ; __arg 运行函数的参数 。

5 当创建线程成功时,函数返回 0 , 若不为 0 则说明创建线程失败,常见的 错误返回代码为 EAGAIN 和 EINVAL 。 前者表示系统限制创建新的线程,例如 线程数目过多了;后者表示第二个参数 代表的线程属性值非法。创建线程成功 后,新创建的线程则运行参数三和参数 四确定的函数,原来的线程则继续运行 下一行代码。

6 线程等待:等待一个线程的结束 int pthread_join __P ((pthread_t __th, void **__thread_return)); __th 被等待的线程标识符, __thread_return 为一个用户定义的指针, 它可以用来存储被等待线程的返回值。这个函 数是一个线程阻塞的函数,调用它的函数将一 直等待到被等待的线程结束为止,当函数返回 时,被等待线程的资源被收回。

7 线程撤消: void pthread_exit __P ((void *__retval)) __attribute__ ((__noreturn__)); 唯一的参数是函数的返回代码,只要 pthread_join 中的第二个参数 thread_return 不是 NULL ,这个值将被传递给 thread_return 。最 后要说明的是,一个线程不能被多个线程等 待,否则第一个接收到信号的线程成功返回, 其余调用 pthread_join 的线程则返回错误代码 ESRCH 。

8 / * 线程示例 */ # include # include 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); } 运行结果 1 This is the main process. This is a pthread. This is the main process. This is the main process. This is a pthread. This is a pthread. 运行结果 2 This is a pthread. This is the main process. This is a pthread. This is the main process. This is a pthread. This is the main process. #gcc example1.c -lpthread -o example1

9 2 、 System V 信号灯 创建一信号灯集: int semget(key_t key,int nsems,int semflg) key 是一个关键字 ,为 IPC_PRIVATE 表明由系统 选用一个关键字; nsems 创建的信号灯个数,信号灯编号为 0 到 nsems-1 ; semflg 创建的权限标志,如 IPC_CREAT|0666 ; /*IPC_CREAT 表示不存在则创建 */ 成功时返回信号灯的 ID ,否则为 -1 。

10 信号灯控制 int semctl(int semid,int semnum,int cmd,union semun arg) semid 是要操作的信号灯集 ID ; semnum 是信号灯集中信号灯的编号; cmd 是操作的命令,常用 SETVAL( 设置信号量 的值 ) 和 IPC_RMID( 删除信号灯 ) arg 给 cmd 的参数。 arg.val = 1; res = semctl(semid,0,SETVAL,arg); semctl(semid,0,IPC_RMID,0)

11 信号灯操作: int semop(int semid,struct sembuf *spos,int nspos) semid 是要操作的信号灯集 ID ; spos 操作数组, nspos 表明数组的个数 。 struct sembuf { short sem_num; /* 使用那一个信号灯 */ short sem_op; /* 进行什么操作 */ short sem_flg; /* 操作的标志,置为 0 ; */ /*IPC_NOWAIT — 不挂起、 SEM_UNDO — 退出还原 */ };

12 sem_op > 0 :将 sem_op 加入到信号灯的值 中, 并唤醒等待信号灯增加的进程; sem_op = 0 :当信号灯的值是 0 的时候, 函 数返回, 否则阻塞直到信号灯的值为 0 ; sem_op < 0 :函数判断信号灯的值加上这 个负值, 结果为 0 唤醒等待信号灯为 0 的 进程, 如果小于 0 函数阻塞,如果大于 0, 那 么从信号于里面减去这个值并返回。

13 对应信号灯 P 操作实现: Void P(int semid,int semno) { struct sembuf sop; sop.sem_num = semno; sop.sem_op = -1; sop.sem_flg = 0; semop(semid,&sop,1); }

14 对应信号灯 V 操作实现: Void V(int semid,int semno) { struct sembuf sop; sop.sem_num = semno; sop.sem_op = 1; sop.sem_flg = 0; semop(semid,&sop,1); }

15 程序结构: main() { 创建信号灯集; 设置互斥 / 同步信号灯初值; 创建子线程; 同步等待子线程退出; 撤消信号灯集; }


Download ppt "实验二 Linux 线程及信号灯 一、目的 了解并掌握 Linux 线程及信号灯。 二、要求 1 、了解 Linux 线程与信号灯使用: ( 1 ) Linux 线程 ( 2 ) Linux 信号灯 ( 3 )线程互斥 ( 4 )线程同步."

Similar presentations


Ads by Google