同步——互斥锁

互斥锁是最基本的同步形式,用于保护临界区

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mptr);
int pthread_mutex_trylock(pthread_mutex_t *mptr);
int pthread_mutex_unlock(pthread_mutex_t *mptr);
// return : 0/errno
// 互斥锁静态初始化
pthread_mutex_t mMutex = PTHREAD_MUTEX_INITIALIZER
// 动态初始化
pthread_mutex_t *mptr = malloc(sizeof(pthread_mutex_t));
pthread_mutex_init(mptr, 0);
// 通常情况下,我们将互斥锁和需要保护的对象封装一个结构体内
struct {
       pthread_mutex_t mutex;
       int shObj;
} shared = {
       PTHREAD_MUTEX_INITIALIZER
};

// 线程间共享互斥锁的生产者消费者
#include	"unpipc.h"

#define	MAXNITEMS 		1000000
#define	MAXNTHREADS			100

int		nitems;			/* read-only by producer and consumer */
struct {
  pthread_mutex_t	mutex;
  int	buff[MAXNITEMS];
  int	nput;
  int	nval;
} shared = { PTHREAD_MUTEX_INITIALIZER };

void	*produce(void *), *consume(void *);

int
main(int argc, char **argv)
{
	int			i, nthreads, count[MAXNTHREADS];
	pthread_t	tid_produce[MAXNTHREADS], tid_consume;

	if (argc != 3)
		err_quit("usage: prodcons2 <#items> <#threads>");
	nitems = min(atoi(argv[1]), MAXNITEMS);
	nthreads = min(atoi(argv[2]), MAXNTHREADS);

	Set_concurrency(nthreads);
		/* 4start all the producer threads */
	for (i = 0; i < nthreads; i++) {
		count[i] = 0;
		Pthread_create(&tid_produce[i], NULL, produce, &count[i]);
	}

		/* 4wait for all the producer threads */
	for (i = 0; i < nthreads; i++) {
		Pthread_join(tid_produce[i], NULL);
		printf("count[%d] = %d\n", i, count[i]);	
	}

		/* 4start, then wait for the consumer thread */
	Pthread_create(&tid_consume, NULL, consume, NULL);
	Pthread_join(tid_consume, NULL);

	exit(0);
}
/* end main */

void *
produce(void *arg)
{
	for ( ; ; ) {
		Pthread_mutex_lock(&shared.mutex);
		if (shared.nput >= nitems) {
			Pthread_mutex_unlock(&shared.mutex);
			return(NULL);		/* array is full, we're done */
		}
		shared.buff[shared.nput] = shared.nval;
		shared.nput++;
		shared.nval++;
		Pthread_mutex_unlock(&shared.mutex);
		*((int *) arg) += 1;
	}
}

void *
consume(void *arg)
{
	int		i;

	for (i = 0; i < nitems; i++) {
		if (shared.buff[i] != i)
			printf("buff[%d] = %d\n", i, shared.buff[i]);
	}
	return(NULL);
}

互斥锁可以用在进程间共享:互斥锁建在共享内存区,并设置PTHREAD_PROCESS_SHARED属性,这样该互斥锁为系统级别

pthread_mutex_t *mptr //point to the mutex in shm
pthread_mutexattr_t mattr;
mptr = /* mutex in shm */
Pthread_mutexattr_init(&mattr);
Pthread_mutexattr_setpshared(&mattr, PTHEAD_PROCESS_SHARED);
Pthread_mutex_init(mptr, &mattr);
当在进程间共享一个互斥锁时,持有该互斥锁的进程在持有期间终止,没有办法让系统在进程终止时自动释放所持有的锁,读写锁和Posix信号量亦然;进程终止时内核总是自动清理的唯一同步锁类型是fcntl记录锁。线程在获取锁的情况下被另一个线程Pthread_cancel掉时,我们可以设置清理处理程序pthread_cleanup_pop/push应对该状况。

你可能感兴趣的:(同步,Linux编程,unix网络编程)