【发布时间】:2025-12-28 22:40:11
【问题描述】:
我正在为餐饮野蛮人问题的某些变量编写 C 解决方案。 现在,我创建线程,每个线程都将 FILE* 获取到同一个调试文件;在线程内部,我正在使用 fprintf() 进行一些打印。打印的语句不受任何类型的互斥锁等保护。
我没有在调试文件中观察到任何交错行为;似乎它是线程安全的,虽然我没有在网上找到一个明确的声明,就是这种情况。
我看到的是以下内容:
- 在 Unix 中,
fprintf是线程安全的 - 使用 c++11 编译器,
fprintf需要是线程安全的
我之所以问这个问题是因为这是一项有效的大学作业,但我仍然怀疑在另一台基于 Windows 的计算机中,由于上述不确定性,该程序可能会导致问题。
我将附上线程代码,以便您看到打印不受保护:
DWORD WINAPI RoomateThread(LPVOID lpParam) {
/*=================================================
"RoomateThread" this is the roomate thread handler function where
the thread logic is implemented
Input: 1. lpParam holds a roomate, runtime and pointers to both files
Output: 1. return an DWORD value {0}->Success {-1}->Failure
2. A code telling if the run was successful (debug file)
A roommate follows this logic after wake up:
1. If there are clothes available in the closet:
a. Wait for mutex to be available, take it
b. Check if the basket is full
b.1. If it is - start the machine and wait for it to finish
c. Throw an item in the basket
d. release mutex
2. If the closet is empty, wait for laundry_is_empty signal, then goto (1.a)
=================================================*/
/*variable declerations*/
DWORD wait_res, delta;
BOOL release_res;
LONG previous_count;
roomate_thread *elem;
elem = (roomate_thread*)lpParam;
/*thread logic*/
while (TRUE) {
/*calculate the delta between the total run time and the time the roomate had run so far*/
delta = total_time - elem->run_time;
/*wait until the minimum between period Ti and delta*/
Sleep(min(elem->roomate->run_time,delta));
fprintf(elem->debug, "RoomateThread(): Line %d, roomate %d: slept for %d mili sec, starting...\n", __LINE__, elem->roomate->roomate_id, min(elem->roomate->run_time, delta));
/*as instructed, each roomate is active since the wakeup*/
fprintf(elem->report, "\nRoomate %d active", elem->roomate->roomate_id);
/*update the element total run time since start*/
elem->run_time = elem->run_time + min(elem->roomate->run_time, delta);
if (time_to_stop < elem->run_time) {
/*if the element total run time is bigger then the global variable update the global*/
time_to_stop = elem->run_time;
}
/*its time to close the thread properly*/
if (time_to_stop == total_time) {
/*if the laundry basket has clothes in it, and the roomate run as much as the total time
activate rhe robot once more and exit*/
if (elem->run_time == total_time && items_in_laundry!=0) {
release_res = ReleaseSemaphore(
laundry_is_full,
1,
&previous_count);
if (release_res == FALSE) {
fprintf(elem->debug, "MachineThread(): Line %d, released semaphore 'laundry_is_full' failed\nthe last error is: 0X%x\n", __LINE__, GetLastError());
return FAILURE;
}
}
break;
}
/*checks that the roomate has clothes in the closet to continue*/
if (elem->roomate->clothes_in_laundry < elem->roomate->clothes-1) {/*roomate has clothes available*/
fprintf(elem->debug, "RoomateThread(): Line %d, roomate id= %d, number of dirty clothes=%d, number of total dirty clothes=%d\n",__LINE__, elem->roomate->roomate_id, elem->roomate->clothes_in_laundry, items_in_laundry);
}
// It's empty:
else {
/*waits until one of the roomates will activate the robot, cause there is no clothes in the roomate closet*/
fprintf(elem->debug, "DAVIDS roomate %d have no clothes, waiting!!!\n", elem->roomate->roomate_id);
elem->roomate->closet_empty = TRUE;
/*Wait until the machine is done*/
wait_res = WaitForSingleObject(laundry_is_empty, INFINITE);
fprintf(elem->debug, "RoomateThread(): Line %d, roomate %d have clothes,finish waiting!!!\n",__LINE__, elem->roomate->roomate_id);
if (wait_res != WAIT_OBJECT_0) {
fprintf(elem->debug, "RoomateThread() error: Line %d, waiting for sempahore 'laundry_is_empty' failed\nthe last error is: 0X%x\n", __LINE__,GetLastError());
return FAILURE;
}
fprintf(elem->debug, "RoomateThread(): Line %d, laundry_is_empty semaphore aquired , roomate: %d\n", __LINE__,elem->roomate->roomate_id);
}
/* Wait for mutex (machine start and clothes add "rights")*/
wait_res = WaitForSingleObject(mutex, INFINITE);
if (wait_res != WAIT_OBJECT_0) {
fprintf(elem->debug, "RoomateThread() error: Line %d, waiting for 'mutex' failed\nthe last error is: 0X%x\n", __LINE__,GetLastError());
return FAILURE;
}
fprintf(elem->debug, "RoomateThread(): Line %d, mutex aquired , roomate: %d\n", __LINE__, elem->roomate->roomate_id);
fprintf(elem->debug, "RoomateThread(): Line 200, mutex aquired , roomate: %d\n",elem->roomate->roomate_id);
/*Check if basket it full*/
if (items_in_laundry == total_items) {
/*Start Machine*/
release_res = ReleaseSemaphore(
laundry_is_full,
1,
&previous_count);
if (release_res == FALSE) {
fprintf(elem->debug, "MachineThread(): Line %d, released semaphore 'laundry_is_empty' failed\nthe last error is: 0X%x\n", __LINE__, GetLastError());
return FAILURE;
}
fprintf(elem->debug, "RoomateThread(): Line 210, released semaphore 'laundry_is_full' last count is: %ld\n", previous_count);
/*Wait for it to finish*/
wait_res = WaitForSingleObject(laundry_is_empty, INFINITE);
if (wait_res != WAIT_OBJECT_0) {
fprintf(elem->debug, "RoomateThread() error: Line %d, waiting for sempahore 'laundry_is_empty' failed\nthe last error is: 0X%x\n", __LINE__, GetLastError());
return FAILURE;
}
items_in_laundry = 0;
}
/*Throw in a dirty cloth*/
elem->roomate->clothes_in_laundry++;
items_in_laundry++;
/*Release the mutex*/
release_res = ReleaseMutex(mutex);
if (release_res == FALSE) {
fprintf(elem->debug, "RoomateThread(): Line %d, released 'mutex' failed\nthe last error is: 0X%x\n", __LINE__, GetLastError());
return FAILURE;
}
fprintf(elem->debug, "RoomateThread(): Line %d, mutex released , roomate: %d\n", __LINE__, elem->roomate->roomate_id);
}
fprintf(elem->debug, "RoomateThread(): Line %d, thread of roomate %d ended\n", __LINE__, elem->roomate->roomate_id);
return SUCSSES;
}
只是提醒一下,这在使用 Visual 2015 的 Windows 上运行
将不胜感激!
**如果您需要更多代码,我将添加,尽管其余代码对所提出的问题没有那么丰富的信息
【问题讨论】:
-
您要链接到哪个版本的 CRT?
-
@MFisherKDX 我真的不知道如何检查它,有什么建议吗?或检查方法
-
@MFisherKDX 好的,我找到了该选项卡,我看到在运行时库中它是多线程 (/MT) 是您想要的吗?如果是这样,我可以在程序开始运行之前重新确保不使用多线程版本吗?
-
是的,那一位化学家。 @MSalters 是对的......自 VS 2005 以来,单线程库已被删除。
-
@user3629249 它不是 C++ 它的 C 我正在使用 CreateThread() 函数,我认为 C 中没有你在评论中所说的等价物
标签: c windows multithreading