现在的位置: 首页 > 综合 > 正文

Linux C编程(5) 线程同步实例

2018年02月15日 ⁄ 综合 ⁄ 共 3934字 ⁄ 字号 评论关闭

线程同步

文件名:main.cpp

编译方法: gcc main.cpp -o testthread -lpthread

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

pthread_mutex_t mutlock;
pthread_cond_t condt;

void Init()
{
	pthread_mutex_init(&mutlock,NULL);
	pthread_cond_init(&condt,NULL);
}

void ActiveThread()
{
	
        pthread_cond_signal(&condt);
}

void * ProcessThread(void * para)
{
	printf("entry process thread");
	while(true)
	{
		pthread_mutex_lock(&mutlock);
		pthread_cond_wait(&condt, &mutlock) ;
		printf("processing...\n");
		//sleep(2); //second
                usleep(2000000); // suspend execution for microsecond intervals
		printf("over\n");
		pthread_mutex_unlock(&mutlock);

	}
	return 0;
}

void * CheckThread(void * para)
{
	while(true)
	{
		usleep(200);
		ActiveThread();
	}
	return 0;
}

int main()
{
	pthread_t tidCheck;
	pthread_t tidProcess;

	Init();
	if(pthread_create(&tidCheck, NULL, CheckThread, NULL) == 0)
	{
		printf("CheckThread create OK!\n");
	}

	if(pthread_create(&tidProcess, NULL, ProcessThread, NULL) == 0)
	{
		printf("Process thread create OK!\n");
	}

	if(pthread_join(tidCheck, NULL) != 0)
	{
		printf("cann't join the thread");
	}

	if(pthread_join(tidProcess, NULL) != 0)
	{
		printf("cann't join the thread");
	}
	return 0;
}

得知ProcessThread线程的工作状态

pthread_cond_wait函数说明

它会先将参数中的锁解锁。然后等待激活信号。等到激活信号后,在次锁定此锁。也就是说,在上面的代码上,锁处于打开状态只有两种可能:

1、执行完了锁定段代码

2、线程处于等待状态。

由此可知,对于上面的代码,只要判断锁的状态,就可以知道,ProcessThread线程是否完成了工作。可以使用trylock函数,检测ProcessThread线程的工作状态。代码如下:

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

pthread_mutex_t mutlock;
pthread_cond_t condt;

void Init()
{
	pthread_mutex_init(&mutlock,NULL);
	pthread_cond_init(&condt,NULL);
}

void ActiveThread()
{
	
        pthread_cond_signal(&condt);
}

void * ProcessThread(void * para)
{
	printf("entry process thread");
	while(true)
	{
		pthread_mutex_lock(&mutlock);
		pthread_cond_wait(&condt, &mutlock) ;
		printf("processing...\n");
		//sleep(2); //second
                usleep(2000000); // suspend execution for microsecond intervals
		printf("over\n");
		pthread_mutex_unlock(&mutlock);

	}
	return 0;
}

void * CheckThread(void * para)
{
	int ret = 0;
	while(true)
	{
		usleep(1000000);
		ret = pthread_mutex_trylock(&mutlock);
		//printf("%d\n", ret);		
		if(ret == 0)
		{
			printf("idle...\n");
			pthread_mutex_unlock(&mutlock);
		}
		else if(ret == 16) //EBUSY=16
		{
			printf("busy...\n");
		}
		ActiveThread();
	}
	return 0;
}

int main()
{
	pthread_t tidCheck;
	pthread_t tidProcess;

	Init();
	if(pthread_create(&tidCheck, NULL, CheckThread, NULL) == 0)
	{
		printf("CheckThread create OK!\n");
	}

	if(pthread_create(&tidProcess, NULL, ProcessThread, NULL) == 0)
	{
		printf("Process thread create OK!\n");
	}

	if(pthread_join(tidCheck, NULL) != 0)
	{
		printf("cann't join the thread");
	}

	if(pthread_join(tidProcess, NULL) != 0)
	{
		printf("cann't join the thread");
	}
	return 0;
}

windows版本如下

#include <windows.h>
#include <stdio.h>


CRITICAL_SECTION criSection;
HANDLE m_hActiveEvent; 
DWORD WINAPI WorkThread( LPVOID lpParam);
DWORD WINAPI CheckThread( LPVOID lpParam);
HANDLE aThread[2];

int main()
{
	InitializeCriticalSection(&criSection);
	m_hActiveEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
	
	DWORD ThreadID;
    aThread[0] = CreateThread( 
                     NULL,       // default security attributes
                     0,          // default stack size
                     (LPTHREAD_START_ROUTINE)WorkThread, 
                     NULL,       // no thread function arguments
                     0,          // default creation flags
                     &ThreadID); // receive thread identifier

	aThread[1]  = CreateThread( 
                     NULL,       // default security attributes
                     0,          // default stack size
                     (LPTHREAD_START_ROUTINE)CheckThread, 
                     NULL,       // no thread function arguments
                     0,          // default creation flags
                     &ThreadID); // receive thread identifier

    
	WaitForMultipleObjects(2, aThread, TRUE, INFINITE);

    // Close thread and mutex handles

    for(int i=0; i < 2; i++ )
        CloseHandle(aThread[i]);
	
	DeleteCriticalSection(&criSection);
	

}

DWORD WINAPI WorkThread( LPVOID lpParam )
{
	int iCount = 0;
	while(true)
	{
		printf("waiting ...%d\n", iCount);
		WaitForSingleObject(m_hActiveEvent, INFINITE); //未触发状态时 线程挂起
		iCount++;
		printf("processing ...\n");

		EnterCriticalSection(&criSection);
	
		Sleep(10*1000);
	
		ResetEvent(m_hActiveEvent);
		LeaveCriticalSection(&criSection);
	}
}

DWORD WINAPI CheckThread( LPVOID lpParam )
{
	BOOL ret;
	while(true)
	{
		Sleep(1*1000);  
        	ret = TryEnterCriticalSection(&criSection);  
        	//printf("%d\n", ret);        
        	if(ret == TRUE)  
        	{  
            		printf("idle...\n");  
			SetEvent(m_hActiveEvent); //ActiveThread
            		LeaveCriticalSection(&criSection);  
        	}  
       	 	else//EBUSY  
        	{  
           		 printf("busy...\n");  
        	}  
       
	}
}

pthread_mutex_trylock 解释见如下网址。

http://www.mkssoftware.com/docs/man3/pthread_mutex_trylock.3.asp

抱歉!评论已关闭.