1、临界区只能用于对象在同一进程里线程间的互斥访问;互斥体可以用于对象进程间或线程间的互斥访问。
2、临界区是非内核对象,只在用户态进行锁操作,速度快;互斥体是内核对象,在核心态进行锁操作,速度慢。
multi_process_mutex2.c
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);
}
}