Linux多线程编程简例六个
Linux多线程编程简例6个
//创建多线程 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> pthread_t ntid; void printids(const char *s) { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid); } void *thr_fn(void *arg) { printids(arg); return NULL; } int main(void) { int err; err = pthread_create(&ntid, NULL, thr_fn, "new thread:"); if(err != 0) { fprintf(stderr, "can't create thread: %s\n", strerror(err));; } printids("main thread:"); sleep(1); return 0; }
//pthread_join #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> void *thr_fn1(void *arg) { printf("thread 1 returning\n"); return (void*)1; } void *thr_fn2(void *arg) { printf("thread 2 exiting\n"); pthread_exit((void*)2); } void *thr_fn3(void *arg) { while(1) { printf("thread 3 writing\n"); sleep(1); } } int main(void) { pthread_t tid; void *tret; pthread_create(&tid, NULL, thr_fn1, NULL); pthread_join(tid, &tret); printf("thread 1 exit code %d\n", (int)tret); pthread_create(&tid, NULL, thr_fn2, NULL); pthread_join(tid, &tret); printf("thread 2 exit code %d\n", (int)tret); pthread_create(&tid, NULL, thr_fn3, NULL); sleep(3); pthread_cancel(tid); pthread_join(tid, &tret); printf("thread 3 exit code %d\n", (int)tret); return 0; }
//演示两个线程操作全局变量时相互干扰 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NLOOP 5000 int counter; void *doit(void *); int main(void) { pthread_t tidA, tidB; pthread_create(&tidA, NULL, &doit, NULL); pthread_create(&tidB, NULL, &doit, NULL); pthread_join(tidA, NULL); pthread_join(tidB, NULL); return 0; } void *doit(void *vptr) { int i, val; for(i=0; i<NLOOP; i++) { val = counter; printf("%x: %d\n", (unsigned int)pthread_self(), val+1); counter = val + 1; } return NULL; }
//演示两个线程操作全局变量时相互干扰, 试用mutex解决 #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NLOOP 5000 int counter; pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;//互斥锁初始化 void *doit(void *); int main(void) { pthread_t tidA, tidB; pthread_create(&tidA, NULL, &doit, NULL); pthread_create(&tidB, NULL, &doit, NULL); pthread_join(tidA, NULL); pthread_join(tidB, NULL); return 0; } void *doit(void *vptr) { int i, val; for(i=0; i<NLOOP; i++) { pthread_mutex_lock(&counter_mutex);//获得锁 val = counter; printf("%x: %d\n", (unsigned int)pthread_self(), val+1); counter = val + 1; pthread_mutex_unlock(&counter_mutex);//解锁 } return NULL; }
// pthread_cond,生产者、消费者模型 #include <stdlib.h> #include <pthread.h> #include <stdio.h> struct msg { struct msg *next; int num; }; struct msg *head; pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void *consumer(void *p) { struct msg *mp; for(;;) { pthread_mutex_lock(&lock); while(head == NULL) { pthread_cond_wait(&has_product, &lock); // 线程调用pthread_cond_wait在一个Condition Variable上 // 阻塞等待,这个函数做以下三步操作: // 1. 释放Mutex // 2. 阻塞等待 // 3. 当被唤醒时,重新获得Mutex并返回 } mp = head; head = mp->next; pthread_mutex_unlock(&lock); printf("Consume -%d\n", mp->num); free(mp); sleep(rand() % 5); } return NULL; } void *producer(void *p) { struct msg *mp; for(;;) { mp = malloc(sizeof(struct msg)); mp->num = rand() % 1000 + 1; printf("Produce +%d\n", mp->num); pthread_mutex_lock(&lock); mp->next = head; head = mp; pthread_mutex_unlock(&lock); pthread_cond_signal(&has_product); // 线程可以调用pthread_cond_signal唤醒在 // 某个Condition Variable上等待的另一个线程 sleep(rand() % 5); } } int main() { pthread_t pid, cid; pthread_create(&pid, NULL, producer, NULL); pthread_create(&cid, NULL, consumer, NULL); pthread_join(pid, NULL); pthread_join(cid, NULL); return 0; }
//sem, 生产者、消费者模型 #include <stdlib.h> #include <pthread.h> #include <stdio.h> #include <semaphore.h> #define NUM 5 sem_t blank_number, product_number; int queue[NUM]; pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void *consumer(void *p) { int n = 0; for(;;) { sem_wait(&product_number); printf("Consume -%d\n", queue[n]); queue[n] = 0; sem_post(&blank_number); n = (n + 1) % NUM; sleep(rand() % 5); } return NULL; } void *producer(void *arg) { int n = 0; for(;;) { sem_wait(&blank_number); queue[n] = rand() % 1000 + 1; printf("Produce +%d\n", queue[n]); sem_post(&product_number); n = (n + 1) % NUM; sleep(rand() % 5); } } int main() { pthread_t pid, cid; sem_init(&blank_number, 0, NUM); sem_init(&product_number, 0, 0); pthread_create(&pid, NULL, producer, NULL); pthread_create(&cid, NULL, consumer, NULL); pthread_join(pid, NULL); pthread_join(cid, NULL); sem_destroy(&blank_number); sem_destroy(&product_number); return 0; }