原文地址:http://blog.csdn.net/monkey_d_meng/article/details/5628663
本文以及原文都是参考了《Linux程序设计第四版》。
一、Linux多线程基础
1.1、Linux进程与线程二、常用函数接口
大多数pthread_XXX系列的函数在失败时,并未遵循UNIX函数的惯例返回-1,这种情况在UNIX函数中属于一少部分。如果调用成功,则返回值是0,如果失败则返回错误代码。#include <pthread.h> int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);参数说明:
#include <pthread.h> void pthread_exit(void *retval);参数说明:
#include <pthread.h> int pthread_join(pthread_t th, void **thread_return);参数说明:
应用实例1:一个简单的多线程Demo(thread1.c)
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void *thread_function(void *arg); char message[] = "Hello World"; int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_create(&a_thread, NULL, thread_function, (void *)message); if (res != 0) { perror("Thread creation failed!"); exit(EXIT_FAILURE); } printf("Waiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed!\n"); exit(EXIT_FAILURE); } printf("Thread joined, it returned %s\n", (char *)thread_result); printf("Message is now %s\n", message); exit(EXIT_FAILURE); } void *thread_function(void *arg) { printf("thread_function is running. Argument was %s\n", (char *)arg); sleep(3); strcpy(message, "Bye!"); pthread_exit("Thank you for your CPU time!"); }编译这个程序时,需要定义宏_REENTRANT:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> int flag = 1; void *thread_function(void *arg); int main() { int res; pthread_t a_thread; void *thread_result; int count = 1; res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } while (count++ <= 20) { if (flag == 1) { printf ("1"); flag = 2; } else { sleep(1); } } printf("\nWaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } void *thread_function(void *arg) { int count = 1; while (count++ <= 20) { if (flag == 2) { printf("2"); flag = 1; } else { sleep(1); } } }编译这个程序:
#include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value);参数说明:
2.信号量控制
#include <semaphore.h> int sem_wait(sem_t *sem); int sem_post(sem_t *sem);sem_post的作用是以原子操作的方式给信号量的值加1。
#include <semaphore.h> int sem_destory(sem_t *sem);这个函数的作用是,用完信号量后对它进行清理,清理该信号量所拥有的资源。如果你试图清理的信号量正被一些线程等待,就会收到一个错误。
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <semaphore.h> #define SIZE 1024 void *thread_function(void *arg); char buffer[SIZE]; sem_t sem; int main() { int res; pthread_t a_thread; void *thread_result; res = sem_init(&sem, 0, 0); if (res != 0) { perror("Sem init failed"); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("Thread create failed"); exit(EXIT_FAILURE); } printf("Input some text. Enter 'end' to finish\n"); while (scanf("%s", buffer)) { sem_post(&sem); if (strncmp("end", buffer, 3) == 0) break; } printf ("\nWaiting for thread to finish...\n"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf ("Thread join\n"); sem_destroy(&sem); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { sem_wait(&sem); while (strncmp("end", buffer, 3) != 0) { printf("You input %d characters\n", strlen(buffer)); sem_wait(&sem); } pthread_exit(NULL); }编译这个程序:
#include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t, *mutexattr); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); int pthread_mutex_destory(pthread_mutex_t *mutex);
与其他函数一样,成功时返回0,失败时将返回错误代码,但这些函数并不设置errno,所以必须对函数的返回代码进行检查。互斥量的属性设置这里不讨论,因此设置成NULL。
应用实例4:
我们用互斥量来重写刚才的代码如下:#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <semaphore.h> #define SIZE 1024 char buffer[SIZE]; void *thread_function(void *arg); pthread_mutex_t mutex; int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_mutex_init(&mutex, NULL); if (res != 0) { perror("Mutex init failed!"); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("Thread create failed!"); exit(EXIT_FAILURE); } printf("Input some text. Enter 'end' to finish\n"); while (1) { pthread_mutex_lock(&mutex); scanf("%s", buffer); pthread_mutex_unlock(&mutex); if (strncmp("end", buffer, 3) == 0) break; sleep(1); } res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed!"); exit(EXIT_FAILURE); } printf("Thread joined\n"); pthread_mutex_destroy(&mutex); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { sleep(1); while (1) { pthread_mutex_lock(&mutex); printf("You input %d characters\n", strlen(buffer)); pthread_mutex_unlock(&mutex); if (strncmp("end", buffer, 3) == 0) break; sleep(1); } }编译这个程序:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> void *thread_function(void *arg); char message[] = "Hello World"; int thread_finished = 0; int main() { int res; pthread_t a_thread; pthread_attr_t thread_attr; res = pthread_attr_init(&thread_attr); if (res != 0) { perror("Attribute creation failed"); exit(EXIT_FAILURE); } res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); if (res != 0) { perror("Setting detached attribute failed"); exit(EXIT_FAILURE); } res = pthread_create(&a_thread, &thread_attr, thread_function, (void*)message); if (res != 0) { perror("Thread creation failed"); exit(EXIT_FAILURE); } pthread_attr_destroy(&thread_attr); while(!thread_finished) { printf("Waiting for thread to say it's finished...\n"); sleep(1); } printf("Other thread finished, bye!\n"); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { printf("thread_function is running. Argument was %s\n", (char *)arg); sleep(4); printf("Second thread setting finished flag, and exiting now\n"); thread_finished = 1; pthread_exit(NULL); }编译这个程序:
#include <pthread.h> int pthread_cancel(pthread_t thread);这个函数简单易懂,提供一个线程标识符,我们就可以发送请求来取消它。
#include <pthread.h> int pthread_setcancelstate(int state, int *oldstate);参数说明:
#include <pthread.h> int pthread_setcanceltype(int type, int *oldtype);参数说明:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> void *thread_function(void *arg); int main() { int res; pthread_t a_thread; void *thread_result; res = pthread_create(&a_thread, NULL, thread_function, NULL); if (res != 0) { perror("Thread create failed!"); exit(EXIT_FAILURE); } sleep(4); printf("Canceling thread...\n"); res = pthread_cancel(a_thread); if (res != 0) { perror("Thread cancel failed!"); exit(EXIT_FAILURE); } printf ("Waiting for thread to finished...\n"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror ("Thread join failed!"); exit(EXIT_FAILURE); } printf("Thread canceled!"); exit(EXIT_FAILURE); } void *thread_function(void *arg) { int i; int res; res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); if (res != 0) { perror("Thread setcancelstate failed!"); exit(EXIT_FAILURE); } res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); if (res != 0) { perror("Thread setcanceltype failed!"); exit(EXIT_FAILURE); } printf("thread_function is running...\n"); for (i = 0; i < 10; i++) { printf("Thread is still running (%d)...\n", i); sleep(1); } pthread_exit(0); }编译这个程序: