【Galileo】Linux多线程
0赞
发表于 8/1/2015 9:04:55 PM
阅读(3125)
最近用galileo做了个东西,东西做好了,开始写些总结,博客里Galileo的文章比较少,因此特开个系列,欢迎有兴趣的人一同交流。首先是Linux的多线程,我就直接以代码来分析了。
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <iostream> using namespace std; struct node { struct node* next; int number; }; pthread_cond_t hasNode = PTHREAD_COND_INITIALIZER;//初始化条件变量 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//初始化互斥锁 struct node* head = NULL; void* get(void *arg) { struct node *node; while(1) { pthread_mutex_lock(&lock); cout<<"1:in the lock"<<endl; if(head == NULL) { printf("1 :has no data...\n"); pthread_cond_wait(&hasNode,&lock);//等待hasnode变量发生改变,同时释放mutex锁 } node = head; head = node->next; printf("1:get the head node number:%d\n",node->number); pthread_mutex_unlock(&lock); cout<<"1:out the lock"<<endl; free(node); //移除获取到的节点 sleep(rand()%5); } } void* put(void *p) { struct node* node; while(1) { node = (struct node* )malloc(sizeof(struct node)); node->number = rand()%1000 +1; printf("2 :put the head node number:%d\n",node->number); pthread_mutex_lock(&lock); cout<<"2:in the lock"<<endl; node->next = head; head = node; pthread_mutex_unlock(&lock); cout<<"2:out the lock"<<endl; pthread_cond_signal(&hasNode); sleep(rand()%5); } } int main() { pthread_t pid,cid; srand(time(NULL));//设置随机种子数,要不然每次程序启动时用 rand() 取得的随机数都是一样的 pthread_create(&pid,NULL,get,NULL);//创建进程get pthread_create(&cid,NULL,put,NULL);//创建进程put pthread_join(pid,NULL);//等待进程get结束 pthread_join(cid,NULL);//等待进程put结束 return 0; }
运行结果:
要理解程序,可以从两个方面入手:
1、互斥锁:
这是为了防止共同访问来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
在线程put和get中,都存在着设置锁和释放锁的操作,两个线程在锁内都都head为头结点的链表进行了操作,这样就能保证共享数据不会出错。
从运行结果可以看出
在一个线程中,上锁和解锁是成对存在的,并且,一个线程上锁后必须解锁后才能让另一个线程访问共享资源;
2、条件变量
线程get中的
if(head == NULL)
{
printf("1 :has no data...\n");
pthread_cond_wait(&hasNode,&lock);//等待hasnode变量发生改变,同时释放mutex锁
}
因为没有了链表,所以必须等待链表的插入操作,即put操作后才能继续等下操作;
运行结果表示,链表为空的情况下,get线程阻塞,等待条件变量变化,并且这个释放锁,转而执行线程put,put的执行使得条件变量发生改变,解锁后,从而又转而执行线程get剩下的部分