1:線程與進程的區別
2:線程同步:互斥鎖
3:線程同步:條件變數
4:線程同步:post訊號量在代碼中有執行個體。5:線程退出
6:線程範例程式碼
/* ============================================================================ Name : threadDemo.c Author : Version : Copyright : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */#include <syslog.h>#include <pthread.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/stat.h>#include <stddef.h> /* For definition of offsetof() */#include <stdarg.h> /* For definition of offsetof() */#include <limits.h>#include <fcntl.h>#include <signal.h>#include <sys/wait.h>#include <sys/types.h> /* Type definitions used by many programs */#include <stdio.h> /* Standard I/O functions */#include <stdlib.h> /* Prototypes of commonly used library functions, plus EXIT_SUCCESS and EXIT_FAILURE constants */#include <unistd.h> /* Prototypes for many system calls */#include <errno.h> /* Declares errno and defines error constants */#include <string.h> /* Commonly used string-handling functions */#include <sys/param.h>#include <pthread.h>#include <semaphore.h>typedef enum { FALSE, TRUE } Boolean;/*使用多線程的理由之一是和進程相比,它是一種非常"節儉"的多任務操作方式。我們知道,在Linux 系統下,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的資料表來維護它的程式碼片段、堆棧段和資料區段,這是一種"昂貴"的多任務工作方式。而運行於一個進程中的多個線程,它們彼此之間使用相同的地址空間,共用大部分資料,啟動一個線程所花費的空間遠遠小於啟動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小於進程間切換所需要的時間。據統計,總的說來,一個進程的開銷大約是一個線程開銷的30 倍左右,當然,在具體的系統上,這個資料可能會有較大的區別 */struct menber{int a;char *s;};void cleanup(void *arg){printf("cleanup arg:%s\n",arg);}void *thread_one(void *arg){pid_t pid;pthread_t tid;pid=getpid();tid=pthread_self();struct menber *parameter=(struct menber *)arg;pthread_cleanup_push(cleanup,(void*)parameter->s); //atexit();printf("thread_one: the pid is %u ,the thread is %u \n",pid,tid);printf("a:%d s:%s\n",parameter->a,parameter->s);pthread_cleanup_pop(1); //pthread_cleanup_pop(0);//atexit();pthread_exit((void *)parameter->a);}void *thread_two(void *arg){pid_t pid;pthread_t tid;pid=getpid();tid=pthread_self();printf("thread_two: the pid is %u ,the thread is %u \n",pid,tid);return (void*)8;}void pthreadParamter(){int err,stat_val;;pid_t pid,childPid;pthread_t tid_one,tid_two;pid=getpid();tid_one=pthread_self();void *retValue_one,*retValue_two;struct menber parameter;parameter.a=123456;parameter.s="suiyuan";if((childPid=fork())==-1){perror("fork");exit(EXIT_FAILURE);}else if(childPid==0){err=pthread_create(&tid_one,NULL,thread_one,(void *)¶meter);if(err!=0){printf("error message is:%s\n",strerror(err));exit(1);}pthread_join(tid_one,&retValue_one);printf("pthread_join,thread_one return value:%d\n",(int)retValue_one);}else{pthread_create(&tid_two,NULL,(void *)thread_two,NULL);if(err!=0){printf("error message is:%s\n",strerror(err));exit(1);}pthread_join(tid_two,&retValue_two);printf("pthread_join,thread_two return value:%d\n",(int)retValue_two);printf("pid:%d getpid:%d\n",pid,getpid());waitpid(childPid, &stat_val, 0);if (WIFEXITED(stat_val)){printf("Child exited with code %d\n", WEXITSTATUS(stat_val));}else if (WIFSIGNALED(stat_val)){printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val));}}printf("main thread:the pid is %u ,the thread is %u \n",pid,tid_one);}/* 如果進程中任何一個線程中調用exit,_Exit,或者是_exit,那麼整個進程就會終止,與此類似,如果訊號的預設的動作是終止進程,那麼,把該訊號發送到線程會終止進程。線程的正常退出的方式:(1) 線程只是從啟動常式中返回,傳回值是線程中的退出碼(2) 線程可以被另一個進程進行終止(3) 線程自己調用pthread_exit 函數 *///************************************************************************************************#if 1static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;#endif#if 1static int avail = 0;static void *pthread_mutex_lock_Func(void *arg){ int cnt = *((int *) arg); int s, j; printf("pthread_mutex_lock_Func:arg:%d\n",cnt); sleep(1); for (j = 0; j < cnt; j++) { sleep(2); /* Code to produce a unit omitted */ s = pthread_mutex_lock(&mtx); if (s != 0) perror("pthread_mutex_lock"); avail++; /* Let consumer know another unit is available */ s = pthread_mutex_unlock(&mtx); if (s != 0) perror("pthread_mutex_unlock");#if 1 s = pthread_cond_signal(&cond); /* Wake sleeping consumer */ if (s != 0) perror("pthread_cond_signal");#endif } return NULL;}void pthread_mutex_lock_test(int num){ pthread_t tid; int s; int totRequired; /* Total number of units that all threads will produce */ int numConsumed; /* Total units so far consumed */ Boolean done; time_t t; t = time(NULL); /* Create all threads */ { totRequired = num; printf("totRequired:%d\n",totRequired); s = pthread_create(&tid, NULL, pthread_mutex_lock_Func, (void *)&totRequired); if (s != 0) perror("pthread_create"); } /* Use a polling loop to check for available units */ numConsumed = 0; done = FALSE; for (;;) { s = pthread_mutex_lock(&mtx); if (s != 0) { perror("pthread_mutex_lock"); } // while (avail == 0) { /* Wait for something to consume */ s = pthread_cond_wait(&cond, &mtx); if (s != 0) perror("pthread_cond_wait"); } // while (avail > 0) { /* Consume all available units */ /* Do something with produced unit */ numConsumed ++; printf("condition is ture;T=%ld: avail=%d numConsumed=%d\n", (long) (time(NULL) - t),avail,numConsumed); avail--; done = numConsumed >= totRequired; } s = pthread_mutex_unlock(&mtx); if (s != 0) { perror("pthread_mutex_unlock"); } if (done) { break; } /* Perhaps do other work here that does not require mutex lock */ } exit(EXIT_SUCCESS);}#endif//***************************************condition example***********************************************#if 1/*static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;*/static int glob = 0;static void cleanupHandler(void *arg) /* Free memory pointed to by 'arg' and unlock mutex */{ int s; printf("cleanup: freeing block at %p\n", arg); free(arg); printf("cleanup: unlocking mutex\n"); s = pthread_mutex_unlock(&mtx); if (s != 0) perror("pthread_mutex_unlock");}static void *mutex_conditionFunc(void *arg){ int s; void *buf = NULL; /* Buffer allocated by thread */ buf = malloc(0x10000); /* Not a cancellation point */ printf("thread: allocated memory at %p\n", buf); s = pthread_mutex_lock(&mtx); /* Not a cancellation point */ if (s != 0) { perror("pthread_mutex_lock"); } pthread_cleanup_push(cleanupHandler, buf); // while (glob == 0) { printf("pthread_cond_wait become to ture\n"); s = pthread_cond_wait(&cond, &mtx); /* A cancellation point */ if (s != 0) { perror("pthread_cond_wait"); } } printf("thread: condition wait loop completed\n"); pthread_cleanup_pop(1); /* Executes cleanup handler */ return NULL;}void mutex_condition_test(int argc){ pthread_t thr; void *res; int s; s = pthread_create(&thr, NULL, mutex_conditionFunc, NULL); if (s != 0) { perror("pthread_create"); } printf("main: sleep 5s\n"); sleep(5); /* Give thread a chance to get started */ if (argc == 1) { /* Cancel thread */ printf("main: about to cancel thread\n"); s = pthread_cancel(thr); if (s != 0) { perror("pthread_cancel"); } } else { /* Signal condition variable */ printf("main: about to signal condition variable\n"); glob = 1; s = pthread_cond_signal(&cond); if (s != 0) { perror("pthread_cond_signal"); } } s = pthread_join(thr, &res); if (s != 0) perror("pthread_join"); if (res == PTHREAD_CANCELED) printf("main: thread was canceled\n"); else printf("main: thread terminated normally\n"); exit(EXIT_SUCCESS);}#endifstatic int globCount = 0;static sem_t postsem;static void * threadPostSemaphoresFunc(void *arg) /* Loop 'arg' times incrementing 'glob' */{ int loops = *((int *) arg); int loc, j; for (j = 0; j < loops; j++) { if (sem_wait(&postsem) == -1) perror("sem_wait"); loc = globCount; loc++; globCount = loc; printf("threadPostSemaphoresFunc:loops %d globCount %d\n",loops, globCount); sleep(1); if (sem_post(&postsem) == -1) perror("sem_post"); } return NULL;}void threadAndPostSemaphoresTest(int loops){ pthread_t t1, t2; int s,loops1=loops+1; /* Initialize a semaphore with the value 1 */ if (sem_init(&postsem, 0, 1) == -1) perror("sem_init"); /* Create two threads that increment 'glob' */ s = pthread_create(&t1, NULL, threadPostSemaphoresFunc, &loops1); if (s != 0) perror("pthread_create"); s = pthread_create(&t2, NULL, threadPostSemaphoresFunc, &loops); if (s != 0) perror("pthread_create"); /* Wait for threads to terminate */ s = pthread_join(t1, NULL); if (s != 0) perror("pthread_join"); s = pthread_join(t2, NULL); if (s != 0) perror("pthread_join"); printf("globCount = %d\n", globCount); exit(EXIT_SUCCESS);}usageError(const char *progName, const char *msg){ if (msg != NULL) { fprintf(stderr, "%s", msg); } fprintf(stderr, "Usage: %s [options] parameter\n", progName); fprintf(stderr, "Usage: %s [tm:c:p:] parameter\n", progName); fprintf(stderr, "Usage: %s -t ;to execute:pthreadParamter()\n", progName); fprintf(stderr, "Usage: %s -m parameter;to execute:pthread_mutex_lock_test()\n", progName); fprintf(stderr, "Usage: %s -c [parameter];to execute:mutex_condition_test()\n", progName); fprintf(stderr, "Usage: %s -p parameter;to execute:threadAndPostSemaphoresTest()\n", progName); fprintf(stderr, "Usage: %s -h ;to execute:help\n", progName); exit(EXIT_FAILURE);}int main(int argc, char *argv[]){int opt;if(argc==1){perror("");usageError(argv[0], NULL);}while ((opt = getopt(argc, argv, "tm:c:k:p:")) != -1) {switch (opt) {case 't':pthreadParamter();break;case 'm':if(optarg!=NULL){printf("optopt:%c :%d\n",optopt,atoi(optarg));pthread_mutex_lock_test(atoi(optarg));}else{usageError(argv[0], NULL);}break;case 'c':if(optarg!=NULL){printf("optopt:%c :%d\n",optopt,atoi(optarg));mutex_condition_test(atoi(optarg));}else{usageError(argv[0], NULL);}break;case 'p':if(optarg!=NULL){printf("optopt:%c :%d\n",optopt,atoi(optarg));threadAndPostSemaphoresTest(atoi(optarg));}else{usageError(argv[0], NULL);}break;default:usageError(argv[0], NULL);}}return EXIT_SUCCESS;}
7:代碼執行結果