三个线程,依次打印

来源:互联网 发布:自我管理的软件 编辑:程序博客网 时间: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");}
原创粉丝点击