【Galileo】Linux多线程
0赞
发表于 8/1/2015 9:04:55 PM
阅读(3672)
最近用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剩下的部分

