编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <pthread.h>
-
#include <unistd.h>
-
#include <string.h>
-
#define DEBUG 1
-
-
int num = 0;
-
pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
-
pthread_cond_t qready=PTHREAD_COND_INITIALIZER;
-
-
void* thread_func(void *arg)
-
{
-
int param = (int) arg;
-
int i;
-
-
for(i = 0; i < 10; i++)
-
{
-
pthread_mutex_lock(&mylock);
-
-
while(param != num)
-
pthread_cond_wait(&qready, &mylock);
-
-
printf("%c", param + 'A');
-
num = (num + 1) % 3;
-
-
pthread_mutex_unlock(&mylock);
-
pthread_cond_broadcast(&qready);
-
}
-
-
return (void *)0;
-
}
-
-
int main()
-
{
-
int i;
-
pthread_t tid[3];
-
void *tret;
-
-
for(i = 0; i < 3; i++)
-
pthread_create(&tid[i], NULL, thread_func, (void *) i);
-
for(i = 0; i < 3; i++)
-
pthread_join(tid[i], &tret);
-
}
首先开辟3个子线程,分别为a,b,c,其中a负责打印'A', b负责打印'B',c负责打印'C'。然后abc开始执行,首先a,b,c都去尝试加锁,其中有一个加锁成功,另外两个则阻塞等待在那里。不妨假设b加锁成功(其实这个可以控制放a先加锁成功);这时a和c线程都阻塞等待加锁,b线程开始执行,当执行到while(param != num),因为他的param是1所以!= num(0),所以他会执行下面的条件变量等待语句,于是他暂时释放当前锁,然后等待在条件变量qread之上。因为此时b释放了锁,那么a和c线程就有机会进入循环了。可以发现如果c获得了锁他的状态和b一样都是阻塞在条件变量之上。于是条件变量就有了一个队列:
c b
这时a就可以执行下面的语句了因为在a线程不执行条件变量等待,然后打印出'A',把num置为1,以此可以让b线程执行。然后a线程释放锁,唤醒所有阻塞在条件变量里面的线程(pthread_cond_broadcast(&qready);),然后b和c就都唤醒了。于是再一次去抢占加锁,不妨假设c抢到了锁,然后他再一次被伤害了,因为他需要执行while语句里面的条件变量等待,此时的条件变量将阻塞a和c线程,于是c再一次被阻塞,理所当然的b执行了线程打印出了‘B',后面的故事就一样了。
如此便可以有效的控制线程的输出顺序!
阅读(11774) | 评论(1) | 转发(2) |