Linux下线程互斥与同步

在Linux环境下进程的互斥是通过创建一个互斥锁来实现的当线程某一资源进行访问时通过给这一资源加锁来防止其他线程对其访问,每一个线程要访问这一资源是必须先申请锁如果得到了锁就可以对资源进行访问,如果没有就会挂起等待。

比如定义一个全局变量用两个线程分别对其进行加加5000次看其结果

#include <pthread.h>


       int pthread_mutex_destroy(pthread_mutex_t *mutex);
       int pthread_mutex_init(pthread_mutex_t *restrict mutex,
              const pthread_mutexattr_t *restrict attr);
       pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

#include <pthread.h>


       int pthread_mutex_lock(pthread_mutex_t *mutex);
       int pthread_mutex_trylock(pthread_mutex_t *mutex);
       int pthread_mutex_unlock(pthread_mutex_t *mutex);


#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>

int g_val = 0;

void* thread1(void* val)
{
	int i=0;
	for(i = 0; i<5000; i++)
	{
		int a = g_val;
		a++;
		printf(" ");
		printf("tid1 = %lu,g_val = %d",pthread_self(),a);
		printf("\n");
		g_val = a;
	}
}

void* thread2(void* val)
{	
	int i = 0;
	for(i = 0; i<5000; i++)
	{
		int a = g_val;
		a++;
		printf(" ");
		printf("tid2 = %lu,g_val = %d",pthread_self(),a);
		printf("\n");
		g_val = a;
	}
}

int main()
{
	pthread_t tid1;
	pthread_t tid2;
	int ret1 = pthread_create(&tid1,NULL,thread1,NULL);
	if (ret1 != 0)
	{
		perror("pthread_create:");
	}

	int ret2 = pthread_create(&tid2,NULL,thread2,NULL);
	if (ret2 != 0)
	{
		perror("pthread_create:");
	}

	void *p1 = NULL;
	void *p2 = NULL;

	pthread_join(tid1,&p1);
	
	pthread_join(tid2,&p2);
	printf("pid = %d,tid1 = %lu,p1 = %d\n",getpid(),tid1,p1);

	printf("pid = %d,tid2 = %lu,p2 = %d\n",getpid(),tid2,p2);

	return 0;
}



对上面的代码稍作改动加入互斥锁



#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>

int g_val = 0;
pthread_mutex_t mutex_lock = PTHREAD_MUTEX_INITIALIZER;

void* thread1(void* val)
{
	int i=0;
	for(i = 0; i<5000; i++)
	{
		pthread_mutex_lock(&mutex_lock);
		int a = g_val;
		a++;
		printf(" ");
		printf("tid1 = %lu,g_val = %d",pthread_self(),a);
		printf("\n");
		g_val = a;
		pthread_mutex_unlock(&mutex_lock);
	}
}

void* thread2(void* val)
{	
	int i = 0;
	for(i = 0; i<5000; i++)
	{
		pthread_mutex_lock(&mutex_lock);
		int a = g_val;
		a++;
		printf(" ");
		printf("tid2 = %lu,g_val = %d",pthread_self(),a);
		printf("\n");
		g_val = a;
		pthread_mutex_unlock(&mutex_lock);
	}
}

int main()
{
	pthread_t tid1;
	pthread_t tid2;
	int ret1 = pthread_create(&tid1,NULL,thread1,NULL);
	if (ret1 != 0)
	{
		perror("pthread_create:");
	}

	int ret2 = pthread_create(&tid2,NULL,thread2,NULL);
	if (ret2 != 0)
	{
		perror("pthread_create:");
	}

	void *p1 = NULL;
	void *p2 = NULL;

	pthread_join(tid1,&p1);
	
	pthread_join(tid2,&p2);
	printf("pid = %d,tid1 = %lu,p1 = %d\n",getpid(),tid1,p1);

	printf("pid = %d,tid2 = %lu,p2 = %d\n",getpid(),tid2,p2);

	return 0;
}


在上面的例子中只体现了线程的互斥并没有体现出线程的同步在某一段时间内都是一个线程的输出

Linux用条件变量来实现进程同步

下面用条件变量来实现线程同步解决生产者消费者问题用一个单链表来作为数据缓冲区


#include <pthread.h>


       int pthread_cond_timedwait(pthread_cond_t *restrict cond,
              pthread_mutex_t *restrict mutex,
              const struct timespec *restrict abstime);
       int pthread_cond_wait(pthread_cond_t *restrict cond,
              pthread_mutex_t *restrict mutex);

 #include <pthread.h>


       int pthread_cond_destroy(pthread_cond_t *cond);
       int pthread_cond_init(pthread_cond_t *restrict cond,
              const pthread_condattr_t *restrict attr);
       pthread_cond_t cond = PTHREAD_COND_INITIALIZER;



#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<assert.h>

typedef struct node
{
	int _data;
	struct node* _next;
}node,*node_p,**node_pp;

node_p alloc_node(int _d)
{
	node_p tmp = (node_p)malloc(sizeof(node));
	if(!tmp)
	{
		perror("malloc :");
		exit(1);
	}

	tmp->_data = _d;
	tmp->_next = NULL;
	return tmp;
}

void push_node(node_p _h,int _d)
{
	assert(_h);

	node_p tmp = alloc_node(_d);
	tmp->_next = _h->_next;
	_h->_next = tmp;
}

void destroy(node_p _h)
{
	assert(_h);

	while(_h)
	{
		pop_node(_h);
	}

	free(_h);
}

int empty(node_p _h)
{
	return (_h->_next == NULL)?1:0;
}

int pop_node(node_p _h)
{
	assert(_h);
	
	int data;
	if(!empty(_h))
	{
		node_p tmp = _h->_next;
		_h->_next = tmp->_next;
		data = tmp->_data;
		free(tmp);
	}

	return data;
}

void init_node(node_pp _h)
{
	assert(_h);
	*_h = alloc_node(0);
}

void print_node(const node_p _h)
{
	assert(_h);

	node_p tmp = _h->_next;

	while(tmp)
	{
		printf("%d ",tmp->_data);
		tmp = tmp->_next;
	}

	printf("\n");
}

pthread_mutex_t lock =PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void* product(void* arg)
{
	node_p h = (node_p)arg;

	while(1)
	{
		pthread_mutex_lock(&lock);

		int data = rand()%1000;
		push_node(h,data);
		printf("product  %d \n",data);

		pthread_mutex_unlock(&lock);
		sleep(1);
		pthread_cond_signal(&cond);
	}
}

void* consumer(void* arg)
{
	node_p h = (node_p)arg;

	while(1)
	{
		pthread_mutex_lock(&lock);

		int data;
		while(empty(h));
		{
			printf("no prodouct...consumer wait\n");
			pthread_cond_wait(&cond,&lock);
			printf("consumer is wake\n");
		}

		data = pop_node(h);
		printf("consumer %d \n",data);

		pthread_mutex_unlock(&lock);
	}
}

int main()
{
	node_p head;
	init_node(&head);
	pthread_t tid1;
	pthread_t tid2;

	pthread_create(&tid1,NULL,product,head);
	pthread_create(&tid2,NULL,consumer,head);

	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_mutex_destroy(&lock);
	pthread_cond_destroy(&cond);
	destroy(head);
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值