天天看點

臨界區和互斥鎖的差別

1、臨界區隻能用于對象在同一程序裡線程間的互斥通路;互斥體可以用于對象程序間或線程間的互斥通路。

2、臨界區是非核心對象,隻在使用者态進行鎖操作,速度快;互斥體是核心對象,在核心态進行鎖操作,速度慢。

3、臨界區和互斥體在Windows平台都下可用;Linux下隻有互斥體可用

互斥體對象用于程序間通信:

multi_process_mutex.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/shm.h>
#include <pthread.h>
#include <errno.h>

#define DEBUG 1
#define SHARE_KEY 0x1234
#define THREAD_NUM 4

typedef struct _Share_Stuff
{
	pthread_mutex_t lock;
	pthread_cond_t cond;
	char msg[180];
	int num;
}Share_Stuff;

static Share_Stuff* stuff[THREAD_NUM];

void* threadB(void *prm);


int main(int argc,char** argv)
{
	 void *share_addr = NULL;
	 pthread_t tid[THREAD_NUM];
	 int shmid = -1;
	 int ret = 0;
	 int i = 0;

	#if DEBUG
		printf("______%s______%s______\n",__DATE__,__TIME__);
	#endif

	share menory
	shmid = shmget(SHARE_KEY, sizeof(Share_Stuff), 0666 | IPC_CREAT);
	if(shmid == -1)
	{
		printf("Create share memory fail! - %s\n", strerror(errno));
	}
	printf("shmid %d\n", shmid);
	
	share_addr = (void*)shmat(shmid, (void*)0, 0);
	if(share_addr < 0)
	{
		printf("Get share memory address error! - %s\n", strerror(errno)); 
	}

	get the addr
	#if DEBUG
		printf("share_addr:%x\n", (unsigned int)share_addr);
	#endif

	for(; i < THREAD_NUM; i++)
	{
		stuff[i] = (Share_Stuff*)share_addr + i;
		stuff[i]->num = i;
		#if DEBUG
			printf("stuff's addr:%x\n",(unsigned int)stuff[i]);
		#endif
	}

	i = 0;
	create_thread
	pthread_condattr_t cond_attr;
	pthread_condattr_init(&cond_attr);
	pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);

	pthread_mutexattr_t mutex_attr;
	pthread_mutexattr_init(&mutex_attr);
	pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);

	for(; i < THREAD_NUM; i++)
	{
		pthread_cond_init(&stuff[i]->cond, &cond_attr);
		pthread_mutex_init(&stuff[i]->lock, &mutex_attr);
		ret=pthread_create(&tid[i],0,threadB,(void*)stuff[i]);
		if(ret != 0)
		{
			printf("ThreadA%d create error!\n",i);
		}
	}

	pthread_condattr_destroy(&cond_attr);
	pthread_mutexattr_destroy(&mutex_attr);

	
	wait_for_done
	for(i = 0; i < THREAD_NUM; i++)
	{
		ret = pthread_join(tid[i], NULL);
	}

	#if DEBUG
		printf("all thread done!\n");
	#endif

	return 0;
}


void* threadB(void *prm)
{
	Share_Stuff *stuff;

	#if DEBUG
		printf("thread's prm:%x\n",(unsigned int)prm);
	#endif

	stuff = (Share_Stuff *)prm;
	while(1)
	{
		sleep(1);
		printf("pthread_cond_wait\n");
		pthread_cond_wait(&stuff->cond,&stuff->lock);
		printf("receive signal, message : %s", stuff->msg);
		/*******************************************************/
		sleep(3); 
		//printf("pthread_mutex_lock\n");
		pthread_mutex_lock(&stuff->lock);
		sprintf(stuff->msg, "threadA -- reply a message %d\n", stuff->num);
		
		printf("pthread_cond_signal\n");
		pthread_cond_signal(&stuff->cond);
		//printf("pthread_mutex_unlock\n");
		pthread_mutex_unlock(&stuff->lock);
	}
}
           

multi_process_mutex2.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/shm.h>
#include <pthread.h>
#include <errno.h>

#define DEBUG 1
#define SHARE_KEY 0x1234
#define THREAD_NUM 4

typedef struct _Share_Stuff
{
	pthread_mutex_t lock;
	pthread_cond_t cond;
	char msg[180];
	int num;
}Share_Stuff;

static Share_Stuff* stuff[THREAD_NUM];

void* threadA(void *prm);


int main(int argc,char** argv)
{
	void *share_addr = NULL;
	pthread_t tid[THREAD_NUM];
	int shmid = -1;
	int ret = 0;
	int i = 0;

	#if DEBUG
		printf("______%s______%s______\n", __DATE__, __TIME__);
	#endif

	share menory
	shmid = shmget(SHARE_KEY, sizeof(Share_Stuff), 0666 | IPC_CREAT);
	if(shmid == -1)
	{
		printf("Create share memory fail! - %s\n",strerror(errno));
	}
	printf("shmid %d\n", shmid);
	
	share_addr = (void*)shmat(shmid,(void*)0,0);
	if(share_addr < 0)
	{
		printf("Get share memory address error! - %s\n",strerror(errno)); 
	}

	get the addr
	#if DEBUG
		printf("share_addr:%x\n", (unsigned int)share_addr);
	#endif

	for(; i < THREAD_NUM; i++)
	{
		stuff[i] = (Share_Stuff*)share_addr+i;
		stuff[i]->num=i;
		#if DEBUG
			printf("stuff's addr:%x\n",(unsigned int)stuff[i]);
		#endif
	}

	
	create_thread

	for(i = 0; i < THREAD_NUM; i++)
	{
		ret = pthread_create(&tid[i], 0, threadA, (void*)stuff[i]);
		if(ret != 0)
		{
			printf("ThreadA%d create error!\n",i);
		}
	}
	
	wait_for_done
	for(i=0; i < THREAD_NUM; i++)
	{
		ret = pthread_join(tid[i], NULL);
	}

	#if DEBUG
		printf("all thread done!\n");
	#endif

	return 0;
}


void* threadA(void *prm)
{
	Share_Stuff *stuff;

	#if DEBUG
	printf("thread's prm:%x\n",(unsigned int)prm);
	#endif

	stuff=(Share_Stuff *)prm;
	while(1)
	{
		sleep(3);
		//printf("pthread_mutex_lock\n");
		pthread_mutex_lock(&stuff->lock);
		sprintf(stuff->msg, "threadB--send message %d\n", stuff->num);
		printf("pthread_cond_signal\n");
		pthread_cond_signal(&stuff->cond); 
		//printf("pthread_mutex_unlock\n");
		pthread_mutex_unlock(&stuff->lock);
		/*******************************************************/
		sleep(1);
		printf("pthread_cond_wait\n");
		pthread_cond_wait(&stuff->cond,&stuff->lock);
		printf("message:%s",stuff->msg);
	}
}
           

繼續閱讀