我並不假定你會使用Linux的線程,因此在這裏就簡單的介紹一下。若是你以前有過多線程方面的編程經驗,徹底能夠忽略本文的內容,由於它很是的初級。
程序員
#include <pthread.h>
固然,進包含一個頭文件是不能搞定線程的,還須要鏈接libpthread.so這個庫,所以在程序鏈接階段應該有相似這樣的指令:算法
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*) void *arg);
#include <stdio.h> #include <pthread.h> void* thread( void *arg ) { printf( "This is a thread and arg = %d.\n", *(int*)arg); *(int*)arg = 0; return arg; } int main( int argc, char *argv[] ) { pthread_t th; int ret; int arg = 10; int *thread_ret = NULL; ret = pthread_create( &th, NULL, thread, &arg ); if( ret != 0 ){ printf( "Create thread error!\n"); return -1; } printf( "This is the main process.\n" ); pthread_join( th, (void**)&thread_ret ); printf( "thread_ret = %d.\n", *thread_ret ); return 0; }
int pthread_detach(pthread_t tid);
int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destory(pthread_attr_t *attr);
那麼線程擁有哪些屬性呢?通常地,Linux下的線程有:綁定屬性、分離屬性、調度屬性、堆棧大小屬性和滿佔警惕區大小屬性。下面咱們就分別來介紹這些屬性。安全
#include <stdio.h> #include <pthread.h> …… int main( int argc, char *argv[] ) { pthread_attr_t attr; pthread_t th; …… pthread_attr_init( &attr ); pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); pthread_create( &th, &attr, thread, NULL ); …… }
pthread_attr_setdetachstat(pthread_attr_t *attr, int detachstate);
它的第二個參數有兩個取值:PTHREAD_CREATE_DETACHED(分離的)和PTHREAD_CREATE_JOINABLE(可合併的,也是默認屬性)。代碼3演示了這個屬性的使用。多線程
#include <stdio.h> #include <pthread.h> …… int main( int argc, char *argv[] ) { pthread_attr_t attr; pthread_t th; …… pthread_attr_init( &attr ); pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); pthread_create( &th, &attr, thread, NULL ); …… }
struct sched_param { int sched_priority; } int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param);
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #define THREAD_COUNT 12 void show_thread_policy( int threadno ) { int policy; struct sched_param param; pthread_getschedparam( pthread_self(), &policy, ¶m ); switch( policy ){ case SCHED_OTHER: printf( "SCHED_OTHER %d\n", threadno ); break; case SCHED_RR: printf( "SCHDE_RR %d\n", threadno ); break; case SCHED_FIFO: printf( "SCHED_FIFO %d\n", threadno ); break; default: printf( "UNKNOWN\n"); } } void* thread( void *arg ) { int i, j; long threadno = (long)arg; printf( "thread %d start\n", threadno ); sleep(1); show_thread_policy( threadno ); for( i = 0; i < 10; ++i ) { for( j = 0; j < 100000000; ++j ){} printf( "thread %d\n", threadno ); } printf( "thread %d exit\n", threadno ); return NULL; } int main( int argc, char *argv[] ) { long i; pthread_attr_t attr[THREAD_COUNT]; pthread_t pth[THREAD_COUNT]; struct sched_param param; for( i = 0; i < THREAD_COUNT; ++i ) pthread_attr_init( &attr[i] ); for( i = 0; i < THREAD_COUNT / 2; ++i ) { param.sched_priority = 10; pthread_attr_setschedpolicy( &attr[i], SCHED_FIFO ); pthread_attr_setschedparam( &attr[i], ¶m ); pthread_attr_setinheritsched( &attr[i], PTHREAD_EXPLICIT_SCHED ); } for( i = THREAD_COUNT / 2; i < THREAD_COUNT; ++i ) { param.sched_priority = 20; pthread_attr_setschedpolicy( &attr[i], SCHED_FIFO ); pthread_attr_setschedparam( &attr[i], ¶m ); pthread_attr_setinheritsched( &attr[i], PTHREAD_EXPLICIT_SCHED ); } for( i = 0; i < THREAD_COUNT; ++i ) pthread_create( &pth[i], &attr[i], thread, (void*)i ); for( i = 0; i < THREAD_COUNT; ++i ) pthread_join( pth[i], NULL ); for( i = 0; i < THREAD_COUNT; ++i ) pthread_attr_destroy( &attr[i] ); return 0; }
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); int pthread_key_delete(pthread_key_t key); void* pthread_getspecific(pthread_key_t key); int pthread_setspecific(pthread_key_t key, const void *value);
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #define THREAD_COUNT 10 pthread_key_t g_key; typedef struct thread_data{ int thread_no; } thread_data_t; void show_thread_data() { thread_data_t *data = pthread_getspecific( g_key ); printf( "Thread %d \n", data->thread_no ); } void* thread( void *arg ) { thread_data_t *data = (thread_data_t *)arg; printf( "Start thread %d\n", data->thread_no ); pthread_setspecific( g_key, data ); show_thread_data(); printf( "Thread %d exit\n", data->thread_no ); } void free_thread_data( void *arg ) { thread_data_t *data = (thread_data_t*)arg; printf( "Free thread %d data\n", data->thread_no ); free( data ); } int main( int argc, char *argv[] ) { int i; pthread_t pth[THREAD_COUNT]; thread_data_t *data = NULL; pthread_key_create( &g_key, free_thread_data ); for( i = 0; i < THREAD_COUNT; ++i ) { data = malloc( sizeof( thread_data_t ) ); data->thread_no = i; pthread_create( &pth[i], NULL, thread, data ); } for( i = 0; i < THREAD_COUNT; ++i ) pthread_join( pth[i], NULL ); pthread_key_delete( g_key ); return 0; }
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr); int pthread_mutex_destory(pthread_mutex_t *mutex ); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex);
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <pthread.h> pthread_mutex_t g_mutex; int g_lock_var = 0; void* thread1( void *arg ) { int i, ret; time_t end_time; end_time = time(NULL) + 10; while( time(NULL) < end_time ) { ret = pthread_mutex_trylock( &g_mutex ); if( EBUSY == ret ) { printf( "thread1: the varible is locked by thread2.\n" ); } else { printf( "thread1: lock the variable!\n" ); ++g_lock_var; pthread_mutex_unlock( &g_mutex ); } sleep(1); } return NULL; } void* thread2( void *arg ) { int i; time_t end_time; end_time = time(NULL) + 10; while( time(NULL) < end_time ) { pthread_mutex_lock( &g_mutex ); printf( "thread2: lock the variable!\n" ); ++g_lock_var; sleep(1); pthread_mutex_unlock( &g_mutex ); } return NULL; } int main( int argc, char *argv[] ) { int i; pthread_t pth1,pth2; pthread_mutex_init( &g_mutex, NULL ); pthread_create( &pth1, NULL, thread1, NULL ); pthread_create( &pth2, NULL, thread2, NULL ); pthread_join( pth1, NULL ); pthread_join( pth2, NULL ); pthread_mutex_destroy( &g_mutex ); printf( "g_lock_var = %d\n", g_lock_var ); return 0; }
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_destory(pthread_cond_t *cond); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, const timespec *abstime); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond);
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #define BUFFER_SIZE 5 pthread_mutex_t g_mutex; pthread_cond_t g_cond; typedef struct { char buf[BUFFER_SIZE]; int count; } buffer_t; buffer_t g_share = {"", 0}; char g_ch = 'A'; void* producer( void *arg ) { printf( "Producer starting.\n" ); while( g_ch != 'Z' ) { pthread_mutex_lock( &g_mutex ); if( g_share.count < BUFFER_SIZE ) { g_share.buf[g_share.count++] = g_ch++; printf( "Prodcuer got char[%c]\n", g_ch - 1 ); if( BUFFER_SIZE == g_share.count ) { printf( "Producer signaling full.\n" ); pthread_cond_signal( &g_cond ); } } pthread_mutex_unlock( &g_mutex ); } printf( "Producer exit.\n" ); return NULL; } void* consumer( void *arg ) { int i; printf( "Consumer starting.\n" ); while( g_ch != 'Z' ) { pthread_mutex_lock( &g_mutex ); printf( "Consumer waiting\n" ); pthread_cond_wait( &g_cond, &g_mutex ); printf( "Consumer writing buffer\n" ); for( i = 0; g_share.buf[i] && g_share.count; ++i ) { putchar( g_share.buf[i] ); --g_share.count; } putchar('\n'); pthread_mutex_unlock( &g_mutex ); } printf( "Consumer exit.\n" ); return NULL; } int main( int argc, char *argv[] ) { pthread_t ppth, cpth; pthread_mutex_init( &g_mutex, NULL ); pthread_cond_init( &g_cond, NULL ); pthread_create( &cpth, NULL, consumer, NULL ); pthread_create( &ppth, NULL, producer, NULL ); pthread_join( ppth, NULL ); pthread_join( cpth, NULL ); pthread_mutex_destroy( &g_mutex ); pthread_cond_destroy( &g_cond ); return 0; }