线程
linux下通过pthread_create创建一个线程:
写道
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
线程执行例程
函数原型:
写道
void* start_routine(void *);
void* start_routine(void *arg) { void *name = (void *) (arg); printf("thread %s called.\n", name); return NULL; } int main() { pthread_t pthread; pthread_create(&pthread, NULL, start_routine, "#1"); return 0; }
gcc pthread_create_test.c -o pthread_create_test -lpthread
写道
linux下创建线程需要用到pthread库,在链接的时候需要将这个库链接进来:-lpthread。最近在整理这方面的东西的时候,发现没有指定-lpthread也可以:
gcc pthread_create_test.c -o pthread_create_test
gcc pthread_create_test.c -o pthread_create_test
linux下C程序主线程结束会终止其他线程的执行,也就是说不会等到其他线程结束之后才结束整个进程。
写道
Any of the threads in the process calls exit(3), or the main thread performs a return from main(). This causes the termination of all threads in the process.
void* start_routine(void *arg) { void *name = (void *) (arg); sleep(10); // sleep 10 seconds. printf("thread %s called.\n", name); return NULL; } int main() { pthread_t pthread; pthread_create(&pthread, NULL, start_routine, "#1"); return 0; }
clean-up handlers & Thread-specific data destructors
相关函数
clean-up handlers:
void pthread_cleanup_push(void (*routine)(void *), void *arg);
void pthread_cleanup_pop(int execute);
void pthread_cleanup_handler(void *arg) { printf("pthread_cleanup_handler called.\n"); }
pthread_cleanup_push(pthread_cleanup_handler, NULL);
pthread_cleanup_pop(0);
例子:
调用pthread_exit函数终止线程时,clean-up handlers将全部弹出并被调用,调用顺序按照push顺序的反顺序。
如果有线程相关数据,在clean-up handlers调用后,对应的Thread-specific data destructors也将被调用,调用顺序未说明。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #include <sys/types.h> int *exitStatus = NULL; void pthread_cleanup_handler(void *arg) { printf("pthread_cleanup_handler called.\n"); } void* run_up(void *arg) { pid_t pid = getpid(); // pid_t tid = gettid(); // Glibc does not provide a wrapper for this system call; call it using syscall(2). pthread_t tid = pthread_self(); printf("pid: %ld, tid: %ld\n", pid, tid); printf("&exitStatus: %d, exitStatus: %d, *exitStatus: %d, &*exitStatus: %d\n", &exitStatus, exitStatus, *exitStatus, &*exitStatus); pthread_cleanup_push(pthread_cleanup_handler, NULL); pthread_exit((void *) exitStatus); pthread_cleanup_pop(0); return (void *) exitStatus; } int main() { exitStatus = (int *) malloc(sizeof(int)); *exitStatus = 8; pthread_t pthread1, pthread2; int result = pthread_create(&pthread1, NULL, run_up, (void *) 0); if (result) { printf("error: pthread_create, errno: %d\n", result); } printf("pthread: %ld\n", pthread1); int *p_status = (int *) malloc(sizeof(int)); int **status = &p_status; result = pthread_join(pthread1, (void **) status); if (result) { printf("error: pthread_join, errno: %d\n", result); } printf("&p_status: %d, p_status: %d, *p_status: %d, &*p_status: %d\n", &p_status, p_status, *p_status, &*p_status); printf("&status: %d, status: %d, *status: %d, &*status: %d, **status: %d, &**status: %d\n", &status, status, *status, &*status, **status, &**status); return 0; }
Thread-specific data destructors:
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));