carlpc

【Galileo】Linux多线程

0
阅读(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剩下的部分