日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【操作系统】使用循环创建线程,一个手残导致的bug

發(fā)布時間:2023/11/30 windows 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【操作系统】使用循环创建线程,一个手残导致的bug 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

讓我們先看看這個手殘的程序……

這是一個簡單的生產者消費者問題。

#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; }

這里最大的問題在后面創(chuàng)建和等待線程的時候

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);}

出于某種原因,樓主將后面的改正確了,前面不知道有問題,這就導致了下面的思考:


創(chuàng)建了線程pthread_t c[5]的數(shù)組,然后使用pthread_join()的時候,不是出現(xiàn)Segmentation fault就是出現(xiàn)pthread join error 3目前還不知道咋回事……

不知道為啥,使用數(shù)組就不行,單獨創(chuàng)建多個變量就沒事……

先在主線程使用pthread_exit(0)而不是return 0暫時避開問題了。


后來找了很多資料也沒有解決,直到發(fā)現(xiàn)……線程創(chuàng)建一直在使用同一個pthread_t變量,并且使用同一個變量,創(chuàng)建了多個線程,而后面在沒改之前,也是使用循環(huán),等待了同一個變量多次……錯錯得對,這個程序居然可以正常運行

不清楚什么情況……后續(xù)再研究對于同一個pthread_t變量創(chuàng)建多個線程且等待多次的情況吧,就很神奇……

總結: 如果太手殘,找bug會很心碎,因為你不知道你哪里手殘了,且不是語法錯誤,而是邏輯錯誤,報錯點也不是你手殘的點。

!!

這里需要注意,對于pthread_join的報錯,得聯(lián)合看看,線程創(chuàng)建好了沒有!是不是joinable的!

總結

以上是生活随笔為你收集整理的【操作系统】使用循环创建线程,一个手残导致的bug的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。