LINUX--信号量、互斥锁和条件变量

Linux 的线程同步机制主要有信号量、互斥量、读写互斥和条件变量等。


信号量

    线程信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制。

    头文件: #include <semaphore.h>

互斥锁

    互斥锁是用来保护临界区的,保证在某时间段内只有一个线程在访问某一资源。

条件变量

    条件变量是一种同步机制,允许线程挂起,直到共享资源上的某些条件得到满足,与线程锁配合使用。

相关函数:

        

pthread_cond_t test_th_cond = PTHREAD_COND_INITIALIZER;                           //申请变量(静态初始化)

int   pthread_cond_init(pthread_cond_t *restrict,const pthread_condattr_t *restrict);   //初始化(动态)

int   pthread_cond_signal(pthread_cond_t *);                                         //设置信号

int   pthread_cond_timedwait(pthread_cond_t *restrict,                              //超时等待
          pthread_mutex_t *restrict, const struct timespec *restrict);                 

int   pthread_cond_wait(pthread_cond_t *restrict,                                 //等待信号(阻塞)
          pthread_mutex_t *restrict);


int   pthread_cond_destroy(pthread_cond_t *);                                    //删除条件变量

int   pthread_cond_broadcast(pthread_cond_t *);                                  //信号广播


例程:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t test_th_mutex;
pthread_cond_t test_th_cond;

#define TH_LOCK_INIT1()		do { \
									pthread_mutexattr_t attr; \
									pthread_mutexattr_init(&attr); \
									pthread_mutex_init(&test_th_mutex, &attr); \
								} while (0)
	//pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP); \		 //可重复进入临界区
#define TH_LOCK_INIT()          pthread_mutex_init(&test_th_mutex, NULL)
#define TH_LOCK()		pthread_mutex_lock(&test_th_mutex)
#define TH_UNLOCK()  	        pthread_mutex_unlock(&test_th_mutex)
#define TH_DESTROY()	        pthread_mutex_destroy(&test_th_mutex)
#define TH_COND_WAIT()	         pthread_cond_wait(&test_th_cond,&test_th_mutex)   
#define TH_COND_SIGNAL()         pthread_cond_signal(&test_th_cond)
#define TH_COND_TIMEWAIT(time)   pthread_cond_timedwait(&test_th_cond, &test_th_mutex, &time)
#define TH_COND_BROADCAST()	 pthread_cond_broadcast(&test_th_cond)
#define TH_COND_DESTROY()        pthread_cond_destroy(&test_th_cond)
#define TH_COND_INIT()           pthread_cond_init(&test_th_cond, NULL)



int set_th_cond_timedwait()
{
    int ret = 0;
    struct timeval now;
    struct timespec time;
    long timeout_ms = 5;                            //+5ms
    gettimeofday(&now, NULL);
    long nsec =now.tv_usec * 1000 +  (timeout_ms % 1000) * 1000000;
    time.tv_sec = now.tv_sec + 5;                     //+5秒
    time.tv_nsec = nsec % 1000000000;                 //纳秒  
    ret = TH_COND_TIMEWAIT(time);               //此时间不是几秒  而是某一时间  类似闹钟
    printf("%d\n",ret);
    return ret;
}


void *test_thread()
{
        int test_cn;
	int i = 0;
	TH_COND_INIT();
	TH_LOCK_INIT();
	sleep(10);
	printf("-----------------------test_th\n");
	while(1)
	{	
		
		TH_LOCK();
#if 0
		TH_COND_WAIT();
#else
		set_th_cond_timedwait();
#endif	
		i++;
		printf("---------------------test_th %d\n",i);
		TH_UNLOCK();
		
	}
	TH_COND_DESTROY();
	TH_DESTROY();

}
void *test_thread1()
{
    while(1)
    {
	printf("--------------------test tt\n");
	TH_COND_SIGNAL();
	//TH_COND_BROADCAST();
    }
}

int test_th()
{
   	pthread_t ThreadId = {0};
        pthread_t ThreadId1 = {0};
	int ret = 0;
	ret = pthread_create(&ThreadId, NULL, test_thread, NULL);
	if(ret){
		printf("pthread_create test_thread ret=%d\n", ret);
		return -1;
	}
		ret = pthread_create(&ThreadId, NULL, test_thread1, NULL);
	if(ret){
		printf("pthread_create test_thread1 ret=%d\n", ret);
		return -1;
	}
	pthread_detach(ThreadId);
        pthread_detach(ThreadId1);
	
         return 0;

}
int main()
{

  test_th();
  return 0;


}

结果

[17:44:50:894]:145
[17:44:50:894]:---------------------test_th 51
[17:44:55:886]:145                                 //超时返回值
[17:44:55:886]:---------------------test_th 52             
[17:45:00:412]:
[17:45:00:911]:---------------------test_th 53
[17:45:01:163]:--------------------test tt         //TH_COND_SIGNAL
[17:45:01:163]:0
[17:45:01:163]:---------------------test_th 54
[17:45:02:536]:
[17:45:05:580]:--------------------test tt         //TH_COND_SIGNAL
[17:45:05:580]:0
[17:45:05:580]:---------------------test_th 55
[17:45:10:586]:145
[17:45:10:586]:---------------------test_th 56




参考:

https://www.cnblogs.com/roger-yu/p/6163712.html

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html


猜你喜欢

转载自blog.csdn.net/qq_37565330/article/details/80181889