三个线程,依次打印
来源:互联网 发布:自我管理的软件 编辑:程序博客网 时间:2024/06/05 11:40
编程实现三个线程ABC,并让它们顺次打印ABC
来源:牛客网的BAT经典面试题
思路:设置三个信号量:S1, S2, S3,S2由S1 post,S3由S2 post, S1由S3 post,由A线程先开始打印,其他线程必然在等待信号量,所以三个线程一定会按照信号量的顺序来打印。
注意vs 2015中多线程使用要调用windows下的API。一般在Linux下用操作系统中讲到的POSIX那一套。
代码实现:
/* * 3个线程逐个执行打印,线程依次控制下一个线程的信号量 */#include <stdio.h>#include <sys/types.h>#include <semaphore.h>#include <pthread.h>sem_t sem_id1, sem_id2, sem_id3;void * func1(void *);void * func2(void *);void * func3(void *);int main(){ //初始化3个信号量 sem_init(&sem_id1, 0, 1); sem_init(&sem_id2, 0, 0); sem_init(&sem_id3, 0, 0); // 创建3个线程 pthread_t pthread_id1, pthread_id2, pthread_id3; pthread_create(&pthread_id1, NULL, &func1, NULL); pthread_create(&pthread_id2, NULL, &func2, NULL); pthread_create(&pthread_id3, NULL, &func3, NULL); // 主进程等待线程执行完毕 pthread_join(pthread_id1, NULL); pthread_join(pthread_id2, NULL); pthread_join(pthread_id3, NULL); return 0;}void * func1(void *){ // 阻塞等待信号量1,等其>0时,信号量-- sem_wait(&sem_id1); printf("A\n"); // 信号量2++ sem_post(&sem_id2);}void * func2(void *){ // 阻塞等待线程1中将信号量2++ sem_wait(&sem_id2); printf("B\n"); // 信号量3++ sem_post(&sem_id3);}void * func3(void *){ // 阻塞等待线程2将信号量3++ sem_wait(&sem_id3); printf("C\n"); // 信号量1++ sem_post(&sem_id1);}// compile and run// 编译选项要加-pthread,否则报错说找不到线程函数g++ -pthread thread_print_in_order.cpp -o test./test
sem_wait sem_post
信号量的数据类型为结构sem_t,它本质上是一个长整型的数。函数sem_init()用来初始化一个信号量。
它的原型为:extern int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,为0时只能为当前进程的所有线程共享;value给出了信号量的初始值。
函数sem_post( sem_t *sem)用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。
函数sem_wait( sem_t *sem)被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。函数sem_trywait (sem_t *sem )是函数sem_wait()的非阻塞版本,它直接将信号量sem的值减一。函数sem_destroy(sem_t *sem)用来释放信号量sem。
若是不使用信号量,则还可以创建一个线程,在该线程中继续创建一个线程,递归的调用下去,等待每个线程返回,不断打印出顺序值。
代码如下:
#include <stdio.h>#include <sys/types.h>#include <pthread.h>void * func1(void *);void * func2(void *);void * func3(void *);int main(){ pthread_t pthread_id1; pthread_create(&pthread_id1, NULL, &func1, NULL); pthread_join(pthread_id1, NULL); return 0;}void * func1(void *){ pthread_t pthread_id1; pthread_create(&pthread_id1, NULL, &func2, NULL); pthread_join(pthread_id1, NULL); // func2执行完才会打印C printf("C\n");}void * func2(void *){ pthread_t pthread_id2; pthread_create(&pthread_id2, NULL, &func3, NULL); pthread_join(pthread_id2, NULL); // func3执行完才会打印B printf("B\n");}void * func3(void *){ printf("A\n");}
- 三个线程,依次打印
- JAVA三个线程依次打印ABC
- 三个线程依次顺序执行
- 详解使用synchronized解决三个线程依次轮流打印出75个数
- 使用Lock,Condition解决三个线程依次轮流打印出75个数
- 保证三个线程依次按顺序执行
- 现有三个线程T1,T2,T3 三个线程依次执行
- C#中添加三个线程同时启动执行某一方法,并依次调用某方法中的循环打印输。
- 使用3个线程依次打印 ABC
- 线程1打印A,线程2打印B,线程3打印C,依次打印10遍
- 三个线程循环打印ABC。。。。
- 三个线程交替打印ABC
- 三个线程顺序打印ABC
- 开启3个线程依次打印ABC10次
- 3个线程依次轮流打印出75个数
- 三个线程循环的按顺序打印
- 三个线程ABC,交替打印ABC
- 循环打印三个线程,ABC 十次
- 图形输出——奥巴马
- 2017/8/3
- DOM3_table相关属性以及Js方法动态添加
- Linux shell脚本中复制特殊字符问题
- linux crontab 定时任务
- 三个线程,依次打印
- HDU-4726-K
- 8.3 自主平衡树学习小结
- 总结一波sql
- 学习中科院杨力祥c++
- Ranger 之java 接口操作
- mongdb添加用户初始化
- 17/8/3学习笔记
- 字典树(Trie树)