1. 程式人生 > >Linux-執行緒

Linux-執行緒

pthread

    pthread_create建立一個執行緒並馬上開始執行執行緒函式;pthread_cancel取消執行緒,可線上程函式中設定“可取消性”的狀態和型別;pthread_join以阻塞方式等待指定執行緒結束,執行緒可用pthread_cancel取消,也可線上程函式中用pthread_exit((void *)val)和return (void *)val結束執行緒,執行緒正常結束時pthread_join(tid, retval)函式retval能收到執行緒結束返回值val,用pthread_cancel取消的返回值是PTHREAD_CANCELED=-1。

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

void *rountine(void *arg)
{
	char *str = (char *)arg;

	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

	int i;
	for(i = 0; i < 5; i++)
	{
		printf("NO.%d: %s \n", i, str);
		sleep(1);
	}

	//pthread_exit((void *)123);
	return (void *)123;
}

int main()
{
	pthread_t tid;
	int ret = pthread_create(&tid, NULL, rountine, "hello world");
	if(ret < 0)
	{
		printf("pthread_create: %d\n", strerror(ret));
		return -1;
	} 

	sleep(3);
	pthread_cancel(tid);

	int i;
	for(i = 0 ; i < 3; i++)
	{
		printf("Main: NO.%d----\n", i);
		sleep(1);
	}

	void *val;
	void **retval=&val;
	ret = pthread_join(tid, retval);
	if(ret < 0)
	{
		printf("pthread_join: %d\n", strerror(ret));
		return -1;
	} 

	printf("val=%d\n", (int)val);
	return 0;
}

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);用來設定當前執行緒的“可取消性”狀態,並且將先前的狀態返回到oldstate引用中;“可取消性”狀態的合法值分別是:PTHREAD_CANCEL_ENABLE 和 PTHREAD_CANCEL_DISABLE。
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);用來設定當前執行緒的“可取消型別”,並且將先前的型別返回到oldtype引用中;“可取消型別”的合法值分別是:PTHREAD_CANCEL_DEFERRED :執行緒接收到取消操作後,直到執行到“可取消點”後取消;PTHREAD_CANCEL_ASYNCHRONOUS :執行緒接收到取消操作後,立即取消;pthread_testcancel

()函式用來在當前執行緒建立一個“可取消點”,如果當前執行緒是不能取消的,則這個函式無效。

sem

    sem訊號量同步

    Compile and link with -std=gnu99 -pthread

#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>

#define MAX 9
char array[MAX];
sem_t sem;

void fun1(int val)
{
	sem_wait(&sem);	//P
	for(int i = 0; i < MAX; i++)
	{
		array[i] = val+i;
		sleep(1);
		printf("fun1: NO.%d: %d \n", i, array[i]);
	}
	sem_post(&sem); //v
}

void fun2(int val)
{
	sem_wait(&sem);	//P
	for(int i = 0; i < MAX; i++)
	{
		array[i] = val+i;
		sleep(1);
		printf("fun2: NO.%d: %d \n", i, array[i]);
	}
	sem_post(&sem); //v
}

void *roun1(void *arg)
{
	fun1(1);
	return (void *)1;
}

void *roun2(void *arg)
{
	fun2(10);
	return (void *)2;
}

int main()
{
	int ret = sem_init(&sem, 0, 1);
	if(0 > ret)
	{
		perror("sem_init");
		return -1;
	}

	pthread_t tid[2];
	ret = pthread_create(&tid[0], NULL, roun1, NULL);
	if(ret < 0)
	{
		printf("pthread_create: %s\n", strerror(ret));
		return -1;
	} 

	sleep(3);
	
	ret = pthread_create(&tid[1], NULL, roun2, NULL);
	if(ret < 0)
	{
		printf("pthread_create: %s\n", strerror(ret));
		return -1;
	} 

	ret = pthread_join(tid[0], NULL);
	if(ret < 0)
	{
		printf("pthread_join: %s\n", strerror(ret));
		return -1;
	}
	ret = pthread_join(tid[1], NULL);
	if(ret < 0)
	{
		printf("pthread_join: %s\n", strerror(ret));
		return -1;
	} 
}

mutex

    mutex互斥鎖互斥

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

#define MAX 9
char array[MAX];
pthread_mutex_t mutex;

void fun(int val)
{
	pthread_mutex_lock(&mutex);
	for(int i = 0; i < MAX; i++)
	{
		array[i] = val+i;
		sleep(1);
		printf("1: NO.%d: %d \n", i, array[i]);
	}
	pthread_mutex_unlock(&mutex);
}

void *roun1(void *arg)
{
	fun(1);
	return (void *)1;
}

void *roun2(void *arg)
{
	fun(10);
	return (void *)2;
}

int main()
{
	int ret = pthread_mutex_init(&mutex, NULL);
	if(0 > ret)
	{
		perror("pthread_mutex_init");
		return -1;
	}

	pthread_t tid[2];
	ret = pthread_create(&tid[0], NULL, roun1, NULL);
	if(ret < 0)
	{
		printf("pthread_create: %s\n", strerror(ret));
		return -1;
	} 

	sleep(3);
	
	ret = pthread_create(&tid[1], NULL, roun2, NULL);
	if(ret < 0)
	{
		printf("pthread_create: %s\n", strerror(ret));
		return -1;
	} 

	ret = pthread_join(tid[0], NULL);
	if(ret < 0)
	{
		printf("pthread_join: %s\n", strerror(ret));
		return -1;
	}
	ret = pthread_join(tid[1], NULL);
	if(ret < 0)
	{
		printf("pthread_join: %s\n", strerror(ret));
		return -1;
	} 
}

條件變數

    與互斥鎖不同,條件變數是用來等待而不是用來上鎖的;條件變數用來自動阻塞一個執行緒,直到某特殊情況發生為止;條件變數使我們可以睡眠等待某種條件出現;條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,
    主要包括兩個動作:
一個執行緒等待"條件變數的條件成立"而掛起;另一個執行緒使"條件成立"(給出條件成立訊號);條件的檢測是在互斥鎖的保護下進行的;如果條件為假,一個執行緒自動阻塞,並釋放等待狀態改變的互斥鎖。

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

//條件變數
pthread_cond_t cont = PTHREAD_COND_INITIALIZER; 
//同步鎖
pthread_mutex_t mutex;
//執行標誌
int bIsrun = 1;

//工作執行緒
void *work(void *arg)
{
	while(1)
	{
		if(0 > pthread_mutex_lock(&mutex))
		{
			exit(-1);
		} 

		if(bIsrun)
		{
			if(0 != pthread_cond_wait (&cont, &mutex))
			{
				exit(-1);
			} 
		}

		if(0 > pthread_mutex_unlock(&mutex))
		{
			perror("work:pthread_mutex_unlock");
			exit(-1);
		}

		static unsigned long counter=0;

		printf("Running - %lu ... \r\n", counter++);
		sleep(1);
	}

	return (void *)0; 
} 

int main(int argv, char **argc)
{  
	// 初始化
	pthread_t thr; 
	pthread_attr_t threadAttr; 
	pthread_attr_init(&threadAttr); 

	pthread_mutex_init(&mutex, NULL);

	pthread_create(&thr, &threadAttr, work, (void *)0);

	//排程執行緒
	while(1)
	{
		char ch = getchar();

		switch(ch)
		{
			/*suspend*/
			case 's':
			case 'S':
				pthread_mutex_lock(&mutex); 
				bIsrun = 1;
				printf("bIsrun = 1\r\n");
				pthread_mutex_unlock (&mutex);
				break;

			/*resume*/
			case 'r':
			case 'R':
				pthread_mutex_lock(&mutex); 
				if(bIsrun)
				{
					bIsrun = 0;
					pthread_cond_signal(&cont);
				} 
				pthread_mutex_unlock (&mutex);
				break;

			/*exit*/
			case 'q':
			case 'Q':
				exit(1);

			default:
				printf("Input something...\r\n");
				break;
		};
 	}

	return 0; 
}