【操作系统】使用循环创建线程,一个手残导致的bug
生活随笔
收集整理的這篇文章主要介紹了
【操作系统】使用循环创建线程,一个手残导致的bug
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
讓我們先看看這個手殘的程序……
這是一個簡單的生產者消費者問題。
#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <unistd.h> #include <pthread.h> #include <sys/types.h> #include <sys/syscall.h>int buffer; int count = 0; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t empty = PTHREAD_COND_INITIALIZER; pthread_cond_t fill = PTHREAD_COND_INITIALIZER;void put(int value){assert(count == 0);buffer = value;count = 1; }int get(){assert(count == 1);count = 0;return buffer; }// gettid pid_t get_thr_tid(){pid_t tid = syscall(__NR_gettid);return tid; }void* producer(void *arg){printf("producer(tid: %d) running\n", get_thr_tid());int loops = *(int *)arg; // gross productfor(int i = 0; i < loops; i++){pthread_mutex_lock(&lock);while(count == 1){ // if the buffer is full,stop producing!pthread_cond_wait(&empty, &lock);}put(i);printf("produce(tid: %d): %d\n", get_thr_tid(), buffer);pthread_cond_signal(&fill); // Wake up the sleepy consumers.pthread_mutex_unlock(&lock);}return NULL; }void* consumer(void *arg){printf(" consumer(tid: %d) running\n", get_thr_tid());int loops = *(int *)arg; // max consume countsfor(int i = 0; i < loops; i++){pthread_mutex_lock(&lock);while(count == 0){ // if the buffer is empty,stop consuming!pthread_cond_wait(&fill, &lock);}int tmp = get(i);printf(" consume(tid: %d): %d\n", get_thr_tid(), tmp);pthread_cond_signal(&empty); // Wake up the sleepy producers.pthread_mutex_unlock(&lock);}return NULL; }int main(int argc, char *argv[]){if(argc != 4){fprintf(stderr,"please input options: <loops> <producer_count> <consumer_count>\n");exit(1);}int loops = atoi(argv[1]);int producer_count = atoi(argv[2]);int consumer_count = atoi(argv[3]);printf("main thread running!\n");// create some threadspthread_t p[producer_count];pthread_t c[consumer_count];for(int i = 0; i < producer_count; i++){pthread_create(&p[producer_count], NULL, producer, (void *)&loops);}for(int i = 0; i < consumer_count; i++){pthread_create(&c[consumer_count], NULL, consumer, (void *)&loops);}for(int i = 0; i < producer_count; i++){pthread_join(p[producer_count], NULL);}for(int i = 0; i < consumer_count; i++){pthread_join(c[consumer_count], NULL);}printf("main thread done!\n");return 0; }這里最大的問題在后面創建和等待線程的時候
for(int i = 0; i < producer_count; i++){pthread_create(&p[producer_count], NULL, producer, (void *)&loops);}for(int i = 0; i < consumer_count; i++){pthread_create(&c[consumer_count], NULL, consumer, (void *)&loops);}for(int i = 0; i < producer_count; i++){pthread_join(p[producer_count], NULL);}for(int i = 0; i < consumer_count; i++){pthread_join(c[consumer_count], NULL);}本來很多地方應該使用i的!實際應該是這樣:
for(int i = 0; i < producer_count; i++){pthread_create(&p[i], NULL, producer, (void *)&loops);}for(int i = 0; i < consumer_count; i++){pthread_create(&c[i], NULL, consumer, (void *)&loops);}for(int i = 0; i < producer_count; i++){pthread_join(p[i], NULL);}for(int i = 0; i < consumer_count; i++){pthread_join(c[i], NULL);}出于某種原因,樓主將后面的改正確了,前面不知道有問題,這就導致了下面的思考:
創建了線程pthread_t c[5]的數組,然后使用pthread_join()的時候,不是出現Segmentation fault就是出現pthread join error 3目前還不知道咋回事……
不知道為啥,使用數組就不行,單獨創建多個變量就沒事……
先在主線程使用pthread_exit(0)而不是return 0暫時避開問題了。
后來找了很多資料也沒有解決,直到發現……線程創建一直在使用同一個pthread_t變量,并且使用同一個變量,創建了多個線程,而后面在沒改之前,也是使用循環,等待了同一個變量多次……錯錯得對,這個程序居然可以正常運行!
不清楚什么情況……后續再研究對于同一個pthread_t變量創建多個線程且等待多次的情況吧,就很神奇……
總結: 如果太手殘,找bug會很心碎,因為你不知道你哪里手殘了,且不是語法錯誤,而是邏輯錯誤,報錯點也不是你手殘的點。
!!
這里需要注意,對于pthread_join的報錯,得聯合看看,線程創建好了沒有!是不是joinable的!
總結
以上是生活随笔為你收集整理的【操作系统】使用循环创建线程,一个手残导致的bug的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 英雄联盟,卡兹克,诺手,女警,买谁好?
- 下一篇: 【计算机系统设计】重点 · 学习笔记(0