【发布时间】:2021-06-12 06:06:29
【问题描述】:
这是我的代码:
#define COUNT_TO 100000000
#define MAX_CORES 4
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
long long i = 0;
void* start_counting(void *arg){
for(;;){
pthread_mutex_lock(&mutex);
if(i >= COUNT_TO){
pthread_mutex_unlock(&mutex);
return NULL;
}
i++;
pthread_mutex_unlock(&mutex);
//printf("i = %lld\n", i);
}
}
int main(int argc, char* argv[]){
int i = 0;
pthread_t * thread_group = malloc(sizeof(pthread_t) * MAX_CORES);
for(i = 0; i < MAX_CORES; i++){
pthread_create(&thread_group[i], NULL, start_counting, NULL);
}
for(i = 0; i < MAX_CORES; i++){
pthread_join(thread_group[i], NULL);
}
return 0;
}
【问题讨论】:
-
因为互斥锁管理不是免费的,而且它的非线程单循环版本可能会优化到几乎没有。
-
所有线程都由锁/解锁序列化。也就是说,没有有效的并行化,但存在运行同步和线程交换的成本。仅仅在问题上抛出线程是不够的。您实际上需要分解工作,以便它可以并行运行而没有主要的互锁,并且工作需要足够重要以使其值得线程切换的开销。
-
我在测试中删除了互斥锁,它改善了多线程的运行时间,但它仍然比单线程慢得多。我是多线程的新手,但我觉得这不应该发生?
-
简短的回答是,正在解决的问题不值得并行化,与正在完成的工作相比,线程开销的成本太高了。在任何情况下,移除锁都不是正确的答案,因为这意味着代码不是线程安全的——它们都试图在竞争条件下读取和递增相同的变量,这意味着代码在功能上变得不正确。
-
不知道 C 是否允许这样做,但在其他语言中,使用智能编译器,您的程序会被编译为一个程序,该程序只需在第一个线程中将
COUNT_TO分配给i其他线程几乎什么都不做。然后,您创建的线程越多,您的开销就越大,而根本不会改变结果。
标签: c multithreading concurrency runtime